Add all of the traversal source files 87/4187/1
authorVenkata Harish K Kajur <vk250x@att.com>
Fri, 12 May 2017 21:36:59 +0000 (17:36 -0400)
committerVenkata Harish K Kajur <vk250x@att.com>
Fri, 12 May 2017 21:37:13 +0000 (17:37 -0400)
Change-Id: Id31f4bdda9c86f782f86829f8b86dada959a9729
Signed-off-by: Venkata Harish K Kajur <vk250x@att.com>
268 files changed:
.gitignore [new file with mode: 0644]
.gitreview [new file with mode: 0644]
LICENSE.TXT [new file with mode: 0644]
aai-traversal/.classpath [new file with mode: 0644]
aai-traversal/.gitignore [new file with mode: 0644]
aai-traversal/ajsc-shared-config/README.txt [new file with mode: 0644]
aai-traversal/ajsc-shared-config/etc/aft.properties [new file with mode: 0644]
aai-traversal/ajsc-shared-config/etc/basic-logback_root_logger_level_off.xml [new file with mode: 0644]
aai-traversal/ajsc-shared-config/etc/csm-config-app.properties [new file with mode: 0644]
aai-traversal/ajsc-shared-config/etc/csm-framework-app.properties [new file with mode: 0644]
aai-traversal/ajsc-shared-config/etc/localhost-access-logback.xml [new file with mode: 0644]
aai-traversal/ajsc-shared-config/etc/logback.xml [new file with mode: 0644]
aai-traversal/antBuild/build.xml [new file with mode: 0644]
aai-traversal/bundleconfig-csi/etc/appprops/app-intercepts.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/README.txt [new file with mode: 0644]
aai-traversal/bundleconfig-local/RELEASE_NOTES.txt [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/Introscope.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/PostProcessorInterceptors.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/PreProcessorInterceptors.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/aaiEventDMaaPPublisher.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/aaiconfig.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/app-intercepts.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/caet.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/default-logback.xml [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/error.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/gremlin-server-config.yaml [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/logging.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/methodMapper.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/preferredRoute.txt [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/titan-cached.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/appprops/titan-realtime.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/auth/aai_keystore [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/query/stored-queries.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getClfiRoadmTailSummary-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComplexByPnfName-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComponentList-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComponentList-1.1.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComponentList-1.2.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVComplexHostname-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVComplexLocationId-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVLogicalLink-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVLogicalLinkByCircuitId-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVServiceTopology-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVServiceTopology-1.1.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVServiceTopology2-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getL3networkCloudRegionByNetworkRole-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getLogicalLinkByCloudRegionId-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getPinterfacePhysicalLinkBySvcInstId-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getRouterRoadmTailSummary-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getServiceInstanceSummary-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getSvcSubscriberModelInfo-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getTenantInfoAtSvcInstance-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getTenantInfoAtSvcSubscription-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getVnfVlanByCircuitId-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getWlBundleId-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/resource-model-json/000-README [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/service-model-json/000-README [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/action-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/action-data-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/allotted-resource-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/availability-zone-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/az-and-dvs-switches-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/class-of-service-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/cloud-region-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/complex-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/connector-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/constrained-element-set-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/ctag-assignment-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/ctag-pool-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/customer-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/cvlan-tag-entry-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/dvs-switch-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/edge-prop-names-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/element-choice-set-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/entitlement-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/flavor-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/generic-vnf-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/group-assignment-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/image-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/include-node-filter-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/instance-group-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/inventory-item-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/inventory-item-data-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/ipsec-configuration-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/key-data-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l-interface-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l3-interface-ipv4-address-list-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l3-interface-ipv6-address-list-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l3-network-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/lag-interface-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/lag-link-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/license-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/license-key-resource-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/logical-link-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/metadatum-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-constraint-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-element-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-ver-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/multicast-configuration-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/named-query-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/named-query-element-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/network-policy-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/network-profile-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/newvce-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/oam-network-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/p-interface-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/physical-link-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/pnf-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/port-group-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/property-constraint-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/pserver-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/related-lookup-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/reserved-prop-names-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/result-data-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/route-table-reference-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/routing-instance-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/secondary-filter-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/segmentation-assignment-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-capability-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-instance-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-subscription-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/site-pair-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/site-pair-set-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/snapshot-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/sriov-vf-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/start-node-filter-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/subnet-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/tagged-inventory-item-list-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/tenant-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/tunnel-xconnect-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/update-node-key-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vce-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vf-module-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vig-server-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/virtual-data-center-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vlan-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vnf-image-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vnfc-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/volume-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/volume-group-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vpe-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vpls-pe-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vpn-binding-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vserver-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/zone-1.0.json [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/service-file-monitor.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/sysprops/sys-props.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/etc/sysprops/template.sys-props.properties [new file with mode: 0644]
aai-traversal/bundleconfig-local/symlinks.txt [new file with mode: 0644]
aai-traversal/pom.xml [new file with mode: 0644]
aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/conf/FileMonitorBeans.xml [new file with mode: 0644]
aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/conf/jaxrsBeans.groovy [new file with mode: 0644]
aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/conf/serviceBeans.xml [new file with mode: 0644]
aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/docs/README.txt [new file with mode: 0644]
aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/lib/README.txt [new file with mode: 0644]
aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/props/module.props [new file with mode: 0644]
aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/routes/aai.route [new file with mode: 0644]
aai-traversal/src/main/assemble/ajsc_module_assembly.xml [new file with mode: 0644]
aai-traversal/src/main/assemble/ajsc_props_assembly.xml [new file with mode: 0644]
aai-traversal/src/main/assemble/ajsc_runtime_assembly.xml [new file with mode: 0644]
aai-traversal/src/main/config/ajsc-jetty.xml [new file with mode: 0644]
aai-traversal/src/main/config/ajsc-jolokia-override-web.xml [new file with mode: 0644]
aai-traversal/src/main/config/ajsc-override-web.xml [new file with mode: 0644]
aai-traversal/src/main/config/ajsc-request.xml [new file with mode: 0644]
aai-traversal/src/main/config/caet.properties [new file with mode: 0644]
aai-traversal/src/main/config/hazelcast-client.properties [new file with mode: 0644]
aai-traversal/src/main/config/jul-redirect.properties [new file with mode: 0644]
aai-traversal/src/main/config/keyfile [new file with mode: 0644]
aai-traversal/src/main/config/realm.properties [new file with mode: 0644]
aai-traversal/src/main/config/runner-web.xml [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/JaxrsErrorMessageLookupService.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/JaxrsUserService.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/filemonitor/ServicePropertiesListener.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/filemonitor/ServicePropertiesMap.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/filemonitor/ServicePropertyService.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/util/ServicePropertiesMapBean.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/db/DbMethHelper.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/DbEdgeGroup.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/DbMeth.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/ModelBasedProcessing.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/ResultSet.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/dbgraphmap/RelationshipGraph.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/dbgraphmap/SearchGraph.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/dmaap/AAIDmaapEventJMSConsumer.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/dmaap/AAIDmaapEventJMSProducer.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/extensions/AAIExtensionMap.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/extensions/ExtensionController.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/interceptors/AAIHeaderProperties.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/interceptors/AAILogJAXRSInInterceptor.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/interceptors/AAILogJAXRSOutInterceptor.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/interceptors/PostAaiAjscInterceptor.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/interceptors/PreAaiAjscInterceptor.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/ExceptionHandler.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/QueryConsumer.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/db/DBRequest.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/db/HttpEntry.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/retired/RetiredConsumer.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/retired/V3ThroughV7Consumer.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/retired/V7V8NamedQueries.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/search/GenericQueryProcessor.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/search/GremlinGroovyShellSingleton.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/search/GremlinServerImpl.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/search/GremlinServerSingleton.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyShellImpl.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/search/ModelAndNamedQueryRestProvider.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/search/QueryProcessorType.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/search/SearchProvider.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/ueb/NotificationEvent.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/ueb/UEBNotification.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/util/EchoResponse.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/util/LogFormatTools.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/rest/util/ValidateEncoding.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/transforms/Converter.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/transforms/LowerCamelToLowerHyphenConverter.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/transforms/LowerHyphenToLowerCamelConverter.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/transforms/MapTraverser.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/util/AAIAppServletContextListener.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/util/RestURL.java [new file with mode: 0644]
aai-traversal/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java [new file with mode: 0644]
aai-traversal/src/main/resources/docker/Dockerfile [new file with mode: 0644]
aai-traversal/src/main/resources/docker/aai.sh [new file with mode: 0644]
aai-traversal/src/main/resources/docker/commonLibs/README [new file with mode: 0644]
aai-traversal/src/main/resources/docker/docker-entrypoint.sh [new file with mode: 0644]
aai-traversal/src/main/resources/docker/init-chef.sh [new file with mode: 0644]
aai-traversal/src/main/resources/schema/UebEventLogEntry.xsd [new file with mode: 0644]
aai-traversal/src/main/runtime/context/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.context [new file with mode: 0644]
aai-traversal/src/main/runtime/context/default#0.context [new file with mode: 0644]
aai-traversal/src/main/runtime/deploymentPackage/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.json [new file with mode: 0644]
aai-traversal/src/main/runtime/shiroRole/ajscadmin.json [new file with mode: 0644]
aai-traversal/src/main/runtime/shiroRole/contextadmin#__module.ajsc.namespace.name__.json [new file with mode: 0644]
aai-traversal/src/main/runtime/shiroRole/contextadmin#default.json [new file with mode: 0644]
aai-traversal/src/main/runtime/shiroUser/ajsc.json [new file with mode: 0644]
aai-traversal/src/main/runtime/shiroUserRole/ajsc#ajscadmin.json [new file with mode: 0644]
aai-traversal/src/main/runtime/shiroUserRole/ajsc#contextadmin#__module.ajsc.namespace.name__.json [new file with mode: 0644]
aai-traversal/src/main/runtime/shiroUserRole/ajsc#contextadmin#default.json [new file with mode: 0644]
aai-traversal/src/main/scripts/getTool.sh [new file with mode: 0644]
aai-traversal/src/main/scripts/install/instutils.sh [new file with mode: 0644]
aai-traversal/src/main/scripts/install/siteconf.pl [new file with mode: 0644]
aai-traversal/src/main/scripts/install/updateQueryData.sh [new file with mode: 0644]
aai-traversal/src/main/scripts/putTool.sh [new file with mode: 0644]
aai-traversal/src/main/xjb/bindings.xjb [new file with mode: 0644]
aai-traversal/src/test/java/org/openecomp/aai/dbgraphgen/DbEdgeGroupTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/openecomp/aai/dbgraphgen/ModelBasedProcessingTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/openecomp/aai/dbgraphmap/SearchGraphEdgeRuleTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/openecomp/aai/rest/search/QueryTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/openecomp/aai/rest/util/ValidateEncodingTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/openecomp/aai/transforms/JoltTestUtil.java [new file with mode: 0644]
aai-traversal/src/test/java/org/openecomp/aai/transforms/LowerHyphenToLowerCamelConverterTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/openecomp/aai/transforms/MapTraverserTest.java [new file with mode: 0644]
aai-traversal/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties [new file with mode: 0644]
aai-traversal/src/test/resources/bundleconfig-local/etc/appprops/error.properties [new file with mode: 0644]
aai-traversal/src/test/resources/bundleconfig-local/etc/auth/aai_policy.json [new file with mode: 0644]
aai-traversal/src/test/resources/config/etc/titan-cached.properties [new file with mode: 0644]
aai-traversal/src/test/resources/config/etc/titan-realtime.properties [new file with mode: 0644]
aai-traversal/src/test/resources/inmemory_titan.properties [new file with mode: 0644]
aai-traversal/src/test/resources/log4j.properties [new file with mode: 0644]
aai-traversal/src/test/resources/logback.xml [new file with mode: 0644]
aai-traversal/src/test/resources/maputils/testcases/TestCase1.json [new file with mode: 0644]
aai-traversal/src/test/resources/maputils/testcases/TestCase2.json [new file with mode: 0644]
aai-traversal/src/test/resources/test_aaiconfig.properties [new file with mode: 0644]
pom.xml [new file with mode: 0644]
set-debug-port.bat [new file with mode: 0644]
start-cassandra-service.bat [new file with mode: 0644]
stop-cassandra-service.bat [new file with mode: 0644]
test_csvWriter.csv [new file with mode: 0644]
version.properties [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..7cb9fb4
--- /dev/null
@@ -0,0 +1,9 @@
+.settings
+.project
+target/
+**/logs/
+bundleconfig-local/etc/auth/aai-client-cert.p12
+bundleconfig-local/etc/logback.xml
+/.pydevproject
+/bin/
+/.classpath
diff --git a/.gitreview b/.gitreview
new file mode 100644 (file)
index 0000000..bbc1709
--- /dev/null
@@ -0,0 +1,4 @@
+[gerrit]
+host=gerrit.onap.org
+port=29418
+project=traversal.git
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644 (file)
index 0000000..32bbcba
--- /dev/null
@@ -0,0 +1,23 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright Â© 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=========================================================
+ *
+ * ECOMP and OpenECOMP are trademarks 
+ * and service marks of AT&T Intellectual Property.
+ *
+ */
diff --git a/aai-traversal/.classpath b/aai-traversal/.classpath
new file mode 100644 (file)
index 0000000..eecfd16
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src/main/java"/>
+       <classpathentry kind="src" path="src/test/resources"/>
+       <classpathentry kind="src" path="src/test/java"/>
+       <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+               <attributes>
+                       <attribute name="owner.project.facets" value="java"/>
+               </attributes>
+       </classpathentry>
+       <classpathentry exported="true" kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+               <attributes>
+                       <attribute name="maven.pomderived" value="true"/>
+               </attributes>
+       </classpathentry>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/aai-traversal/.gitignore b/aai-traversal/.gitignore
new file mode 100644 (file)
index 0000000..cd21128
--- /dev/null
@@ -0,0 +1,10 @@
+.settings
+target/
+**/logs/
+bundleconfig-local/etc/auth/aai-client-cert.p12
+bundleconfig-local/etc/oxm
+src/main/aai_schema
+bundleconfig-local/etc/logback.xml
+/.pydevproject
+/test_csvWriter.csv
+/bin/
diff --git a/aai-traversal/ajsc-shared-config/README.txt b/aai-traversal/ajsc-shared-config/README.txt
new file mode 100644 (file)
index 0000000..a82eb64
--- /dev/null
@@ -0,0 +1,6 @@
+The ajsc-shared-config folder is included in the service project to provide the functionality of the AJSC_SHARED_CONFIG 
+location that will exist in CSI envs. This includes the logback.xml for logging configurations, and some csm related 
+artifacts necessary for proper functionality of the csm framework within the CSI env. Within the 2 profiles that can 
+be utilized to run the AJSC locally, "runLocal" and "runAjsc", the system propery, "AJSC_SHARED_CONFIG", has been set
+to point to this directory. The files in this folder will NOT be copied/moved anywhere within the AJSC SWM package. These 
+files will already be in existence within the CSI env.
\ No newline at end of file
diff --git a/aai-traversal/ajsc-shared-config/etc/aft.properties b/aai-traversal/ajsc-shared-config/etc/aft.properties
new file mode 100644 (file)
index 0000000..43e896d
--- /dev/null
@@ -0,0 +1,13 @@
+
+# Flow test 319
+com.att.aft.discovery.client.environment=AFTUAT
+com.att.aft.discovery.client.latitude=35.318900
+com.att.aft.discovery.client.longitude=-80.762200
+com.att.aft.alias=ecomp-aai
+#com.att.aft.keyStore=ajsc-shared-config/etc/spm2.jks
+com.att.aft.keyStore=/opt/app/aai/bundleconfig/etc/m04353t.jks
+com.att.aft.keyStorePassword=its4test
+#com.att.aft.trustStore=ajsc-shared-config/etc/spm2.jks
+com.att.aft.trustStore=/opt/app/aai/bundleconfig/etc/m04353t.jks
+com.att.aft.trustStorePassword=its4test
+
diff --git a/aai-traversal/ajsc-shared-config/etc/basic-logback_root_logger_level_off.xml b/aai-traversal/ajsc-shared-config/etc/basic-logback_root_logger_level_off.xml
new file mode 100644 (file)
index 0000000..326c8cb
--- /dev/null
@@ -0,0 +1,84 @@
+<configuration scan="true" scanPeriod="3 seconds" debug="true">
+       <property name="logDirectory" value="${AJSC_HOME}/log" />
+       <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>ERROR</level>
+               </filter>
+               <encoder>
+                       <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - %msg%n
+                       </pattern>
+               </encoder>
+       </appender>
+
+       <appender name="INFO"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>DEBUG</level>
+               </filter>
+               <file>${logDirectory}/info_ajsc.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+                       <fileNamePattern>${logDirectory}/info_ajsc.%i.log.zip
+                       </fileNamePattern>
+                       <minIndex>1</minIndex>
+                       <maxIndex>9</maxIndex>
+               </rollingPolicy>
+               <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize>
+               </triggeringPolicy>
+               <encoder>
+                       <pattern>"%d [%thread] %-5level %logger{1024} - %msg%n"</pattern>
+               </encoder>
+       </appender>
+       <appender name="ERROR"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>ERROR</level>
+               </filter>
+               <file>${logDirectory}/error_ajsc.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+                       <fileNamePattern>${logDirectory}/error_ajsc.%i.log.zip
+                       </fileNamePattern>
+                       <minIndex>1</minIndex>
+                       <maxIndex>9</maxIndex>
+               </rollingPolicy>
+               <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize>
+               </triggeringPolicy>
+               <encoder>
+                       <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - %msg%n"</pattern> -->
+                       <pattern>"%d [%thread] %-5level %logger{1024} - %msg%n"</pattern>
+               </encoder>
+       </appender>
+
+       <appender name="AJSC-AUDIT" class="ch.qos.logback.classic.net.SyslogAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>INFO</level>
+               </filter>
+               <syslogHost>localhost</syslogHost>
+               <facility>USER</facility>
+               <!-- Note the colon character below - it is important part of "TAG" message 
+                       format You need a colon to determine where the TAG field ends and the CONTENT 
+                       begins -->
+               <suffixPattern>AJSC_AUDIT: [%thread] [%logger] %msg</suffixPattern>
+       </appender>
+       <appender name="CONTROLLER-AUDIT" class="ch.qos.logback.classic.net.SyslogAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>INFO</level>
+               </filter>
+               <syslogHost>localhost</syslogHost>
+               <facility>USER</facility>
+               <!-- Note the colon character below - it is important part of "TAG" message 
+                       format You need a colon to determine where the TAG field ends and the CONTENT 
+                       begins -->
+               <suffixPattern>AJSC_AUDIT: [%thread] [%logger] mdc:[%mdc] %msg
+               </suffixPattern>
+       </appender>
+
+       <root level="off">
+               <appender-ref ref="ERROR" />
+               <appender-ref ref="INFO" />
+               <appender-ref ref="STDOUT" />
+       </root>
+</configuration>
diff --git a/aai-traversal/ajsc-shared-config/etc/csm-config-app.properties b/aai-traversal/ajsc-shared-config/etc/csm-config-app.properties
new file mode 100644 (file)
index 0000000..b4d0476
--- /dev/null
@@ -0,0 +1,183 @@
+Global.ExtendedProperty.AuthoritativeServers=${ChangeMe_csm.acfshost}:${ChangeMe_csm.acfsport}
+
+#
+# The settings in this file control the behavior of the CSM Framework. 
+# The majority of the settings in this file adhere to the following
+# pattern:
+# 
+#  [EntityType].[EntityId].[PropertyName]=[PropertyValue]
+# 
+# Where:
+# 
+#  [EntityType]    Identifies the type of entity (service or
+#                  service group) that's being configured.
+#  [EntityId]      Identifies the individual entity.
+#  [PropertyName]  Identifies the property that is being set.
+#  [PropertyValue] Is the actual property value.
+# 
+# In the formatting sample above, the EntityType can be setto one of the
+# following values:
+# 
+#  * 'Service' if an individual service is being configured.
+#  * 'Group 'if a service group is being configured.
+# 
+# The reference to 'entity' in the above description is intentionally
+# generic.  The CSM Framework supports the configuration of individual
+# services as well as groups of services.  The type of entity that is
+# actually being configured is determined by the value of the
+# [EntityType] portion of the property.
+# 
+# There are two values for [EntityId] that have a special meaning within
+# the CSM Framework:
+# 
+# 
+# DefaultService - Identifies the default configuration for any service
+#     that is not explicitly configured elsewhere in this file.
+# 
+# DefaultServiceGroup - This identifies the entity that provides the
+#     default configuration for any service group that is not explicitly
+#     configured elsewhere in this file.
+# 
+# DO NOT use either of these as the identifier for any of your
+# application-specific services or service groups.
+# 
+# The CSM Framework treats all entity identifiers in a case-insensitive
+# manner.  The entity ids 'Service1' and 'SERVICE1' are equivalant.  All
+# properties with the same [EntityId] will be applied to the same
+# configuration.  The CSM Framework framework also treats property names
+# in a case-insensitive manner.  'MaxRequestCount' and 'MAXREQUESTCOUNT'
+# are considered equivalent within the CSM framework.
+# 
+# The following properties are supported by the CSM Framework.  Any
+# properties that are entity-specific will include the '[EntityId].'
+# prefix.
+# 
+# [EntityType].[EntityId].Enabled - Indicates if the entity is enabled
+#     or disabled by default.  The value of this property must be either
+#     'true' or 'false'.
+# 
+# [EntityType].[EntityId].MaxRequestCount - The maximum number of
+#     requests that can be running at any point in time.  Once this limit is
+#     reached, the service is considered  to be 'flooded', and subsequent
+#     requests are refused until the request count drops to the level
+#     specified by the RestartThreshold property.  Once the restart
+#     threshold is reached, the service will be 'restarted' based on the
+#     values of the 'RestartFrequency' and 'RestartIncrement' properties.
+#     The value of this property must be a numeric value.
+#     The default value for this property is 20.
+# 
+# [EntityType].[EntityId].MaxStalledRequestCount - the maximum number of
+#     'stalled' requests that are allowed before subsequent requests are
+#     refused
+#     The value of this property must be a numeric value.
+#     The default value for this property is 10.
+# 
+# [EntityType].[EntityId].RestartThreshold - the process count level at
+#     which requests will be allowed to proceed whenever a service becomes
+#     'flooded'.  This property is only used if the total process count
+#     reaches the level set by the 'MaxRequestCount' property.  Once that
+#     occurs, subsequent requests will be refused until the active request
+#     count drops to the level specified by this property.  Once the active
+#     request count drops to the level specified by this property, the
+#     service will be 'restarted' based on the values of the
+#     'RestartFrequency' and 'RestartIncrement' properties.  To cause the
+#     CSM framework to allow subsequent requests to proceed as soon as the
+#     active request count drops below level level set by the
+#     'MaxRequestCount' property, just set this property to either -1 or 1
+#     less than the value of the 'MaxRequestCount' property.
+#     The value of this property must be a numeric value.
+#     The default value for this property is -1.
+# 
+# [EntityType].[EntityId].RestartIncrement - This property, along with
+#     the 'RestartFrequency' property helps determine how quickly the active
+#     request count will rise to the 'maximum request count' whenever a
+#     service is 'restarted' after becoming 'flooded'. The
+#     'RestartFrequency' property determines how frequenty the permissable
+#     number of active requests will be increased.  This property determines
+#     how much the permissible number of active requests will increase by
+#     whenever it is raised.  If this property is set to a positive value,
+#     then the 'RestartFrequency' property must also be set to a positive
+#     value.  If this property is set to 0, then the 'RestartFrequency'
+#     property must also be set to 0.  In other words, either both
+#     properties are 0 or both properties are greater than 0.  When both
+#     properties are set to 0, then the permissable number of active
+#     requests immediately rises back up to the maximum request count once
+#     it has droppedback down to the 'restart threshold'.  When both
+#     properties are greater than 0, then the permissable number of active
+#     requests gradually rises to the maximum request count.
+#     The value of this property must be a numeric value greater than or equal to 0.
+#     The default value for this property is 0.
+# 
+# [EntityType].[EntityId].RestartFrequency - This property, along with
+#     the 'RestartIncrement' property helps determine how quickly the active
+#     request count will rise to the 'maximum request count' whenever a
+#     service is 'restarted' after becoming 'flooded'. The
+#     'RestartIncrement' property determines how quickly the permissable
+#     number of active requests will be increased.  This property determines
+#     how frequently  that increase will occur.  If this property is set to
+#     a positive value, then the 'RestartIncrement' property must also be
+#     set to a positive value.  If this property is set to 0, then the
+#     'RestartIncrement' property must also be set to 0.  In other words,
+#     either both properties are 0 or both properties are greater than 0. 
+#     When both properties are set to 0, then the permissable number of
+#     active requests immediately rises back up to the maximum request count
+#     once it has droppedback down to the 'restart threshold'.  When both
+#     properties are greater than 0, then the permissable number of active
+#     requests gradually rises to the maximum request count.
+#     The value of this property must be a numeric value greater than or equal to 0.
+#     The default value for this property is 0.
+# 
+# [EntityType].[EntityId].ServiceGroupId - This property is only
+#     relevant for entities that are configured as services (i.e. the
+#     [EntityType] portion of the property is set to 'Service').  When the
+#     'ServiceGroupId' property is set to a non-blank value, the behavior of
+#     the service is controled by the configuration of the corresponding
+#     service group.  There is no default value for this property.
+# 
+# [EntityType].[EntityId].Timeout - the timeout, in milliseconds, for
+#     each process that is controlled by this configuration.  Once the
+#     duration of a process exceeds this value, the process will be
+#     considered to have entered a 'stalled' state.  The default value for
+#     this property is 10000.
+# 
+# FrameworkEnabled: - This is the one property that is not specific to a
+#     single entity.  This property determines whether the entire CSM
+#     Framework is enabled or disabled.  When disabled, the CSM Framework
+#     does not track any process counts.  All requests to access a service
+#     are allowed, regardless of the current level of activity.  The value
+#     of this property must be either 'true' or 'false'.
+# 
+
+#
+# Enables the CSM Framework so that it can manage interactions with external
+# services and/or resources.  To disable the CSM Framework, simply set
+# this property to false.
+#
+FrameworkEnabled=true
+
+#
+# These are the default settings for any service that is no explicitly configured
+# below.  A few things to note about this configuration:
+#  1) The "Enabled" property is not explicitly set.  Instead, we are relying
+#     on the default value of 'true'.
+#  2) The Timeout and Type properties are also not explicitly set.  Again, we
+#     are relying on the default values for these properties.
+#  
+Service.DefaultService.Enabled=true
+Service.DefaultService.MaxRequestCount=30
+Service.DefaultService.MaxStalledRequestCount=20
+Service.DefaultService.Timeout=30000
+Service.DefaultService.RestartThreshold=-1
+Service.DefaultService.AutoPurgeAfter=150000
+
+
+#
+# These are the default settings for any service group that is referenced in 
+# a service configuration but not configured below.
+# 
+# Currently CSI does not use any service group configurations!
+#
+#Group.DefaultGroup.MaxRequestCount=-1
+#Group.DefaultGroup.MaxStalledRequestCount=-1
+#Group.DefaultGroup.RestartThreshold=-1
+#Group.DefaultGroup.Timeout=-1
diff --git a/aai-traversal/ajsc-shared-config/etc/csm-framework-app.properties b/aai-traversal/ajsc-shared-config/etc/csm-framework-app.properties
new file mode 100644 (file)
index 0000000..140fde3
--- /dev/null
@@ -0,0 +1,11 @@
+# The csm-persist-to property identifies the file that the CSM Framework
+# will write the current configuration to whenever it is told to save it's
+# configuration.
+#
+#csm-persist-to=/opt/app/myapplication/csm.properties.persisted
+
+#Important . Please specify absolute path starting from the root directory for Property csm-persist-to 
+#(Giving relative path may result in undesired results in case the applcation is restarted from a different directory than the original start directory  )
+#In the following example , relative path is specfied since the directory structure varies on diff env 
+
+csm-persist-to=/opt/app/q103csi1m8/DATA/${ChangeMe_RELEASE}/${ChangeMe_CLUSTER}_ACFS_csm.properties.persisted
diff --git a/aai-traversal/ajsc-shared-config/etc/localhost-access-logback.xml b/aai-traversal/ajsc-shared-config/etc/localhost-access-logback.xml
new file mode 100644 (file)
index 0000000..cf37962
--- /dev/null
@@ -0,0 +1,38 @@
+<configuration>
+       <appender name="ACCESS"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <file>${AJSC_HOME}/logs/ajsc-jetty/localhost_access.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${AJSC_HOME}/logs/ajsc-jetty/localhost_access.log.%d{yyyy-MM-dd}
+                       </fileNamePattern>
+               </rollingPolicy>
+               <encoder class="org.openecomp.aai.logging.CustomLogPatternLayoutEncoder">
+                       <Pattern>%a %u %z [%t] "%m %U" %s %b %y %i{X-TransactionId} %i{X-FromAppId} %i{X-Forwarded-For} %i{X-AAI-SSL-Client-CN} %i{X-AAI-SSL-Client-OU} %i{X-AAI-SSL-Client-O} %i{X-AAI-SSL-Client-L} %i{X-AAI-SSL-Client-ST} %i{X-AAI-SSL-Client-C} %i{X-AAI-SSL-Client-NotBefore} %i{X-AAI-SSL-Client-NotAfter} %i{X-AAI-SSL-Client-DN} %D</Pattern>
+               </encoder>
+       </appender>
+       <appender-ref ref="ACCESS" />
+</configuration>
+
+<!-- 
+%a - Remote IP address
+%A - Local IP address
+%b - Bytes sent, excluding HTTP headers, or '-' if no bytes were sent
+%B - Bytes sent, excluding HTTP headers
+%h - Remote host name
+%H - Request protocol
+%l - Remote logical username from identd (always returns '-')
+%m - Request method
+%p - Local port
+%q - Query string (prepended with a '?' if it exists, otherwise an empty string
+%r - First line of the request
+%s - HTTP status code of the response
+%S - User session ID
+%t - Date and time, in Common Log Format format
+%u - Remote user that was authenticated
+%U - Requested URL path
+%v - Local server name
+%I - current request thread name (can compare later with stacktraces)
+
+%z - Custom pattern that parses the cert for the subject
+%y - Custom pattern determines rest or dme2
+ -->
\ No newline at end of file
diff --git a/aai-traversal/ajsc-shared-config/etc/logback.xml b/aai-traversal/ajsc-shared-config/etc/logback.xml
new file mode 100644 (file)
index 0000000..3311342
--- /dev/null
@@ -0,0 +1,382 @@
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+       <contextName>${module.ajsc.namespace.name}</contextName>
+       <jmxConfigurator />
+       <property name="logDirectory" value="${AJSC_HOME}/logs" />
+       <property name="eelfLogPattern" value="%ecompStartTime|%date{yyyy-MM-dd'T'HH:mm:ss.SSSZ, UTC}|%X{requestId}|%X{serviceInstanceId}|%-10t|%X{serverName}|%X{serviceName}|%X{partnerName}|%X{statusCode}|%X{responseCode}|%X{responseDescription}|%X{instanceUUID}|%level|%X{severity}|%X{serverIpAddress}|%ecompElapsedTime|%X{server}|%X{clientIpAddress}|%eelfClassOfCaller|%X{unused}|%X{processKey}|%X{customField1}|%X{customField2}|%X{customField3}|%X{customField4}|co=%X{component}:%replace(%m){'\n', '^'}%n"/>
+       <property name="eelfAuditLogPattern" value="%ecompStartTime|%date{yyyy-MM-dd'T'HH:mm:ss.SSSZ, UTC}|%X{requestId}|%X{serviceInstanceId}|%-10t|%X{serverName}|%X{serviceName}|%X{partnerName}|%X{statusCode}|%X{responseCode}|%X{responseDescription}|%X{instanceUUID}|%level|%X{severity}|%X{serverIpAddress}|%ecompElapsedTime|%X{server}|%X{clientIpAddress}|%eelfClassOfCaller|%X{unused}|%X{processKey}|%X{customField1}|%X{customField2}|%X{customField3}|%X{customField4}|co=%X{component}:%replace(%m){'\n', '^'}%n"/>
+       <property name="eelfMetricLogPattern" value="%ecompStartTime|%date{yyyy-MM-dd'T'HH:mm:ss.SSSZ, UTC}|%X{requestId}|%X{serviceInstanceId}|%-10t|%X{serverName}|%X{serviceName}|%X{partnerName}|%X{targetEntity}|%X{targetServiceName}|%X{statusCode}|%X{responseCode}|%X{responseDescription}|%X{instanceUUID}|%level|%X{severity}|%X{serverIpAddress}|%ecompElapsedTime|%X{server}|%X{clientIpAddress}|%eelfClassOfCaller|%X{unused}|%X{processKey}|%X{targetVirtualEntity}|%X{customField1}|%X{customField2}|%X{customField3}|%X{customField4}|co=%X{component}:%replace(%m){'\n', '^'}%n"/>
+
+       <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+               <filter class="ch.qos.logback.classic.filter.LevelFilter">
+                       <level>ERROR</level>
+                       <onMatch>ACCEPT</onMatch>
+                       <onMismatch>DENY</onMismatch>
+               </filter>
+               <encoder>
+                       <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - %msg%n
+                       </pattern>
+               </encoder>
+       </appender>
+
+       <appender name="SANE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <file>${logDirectory}/rest/sane.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/sane.log.%d{yyyy-MM-dd}</fileNamePattern>
+               </rollingPolicy>
+               <encoder>
+                       <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - %msg%n
+                       </pattern>
+               </encoder>
+       </appender>
+
+       <appender name="asyncSANE" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>1000</queueSize>
+               <includeCallerData>true</includeCallerData>
+               <appender-ref ref="SANE" />
+       </appender>
+
+       <appender name="METRIC"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.LevelFilter">
+                       <level>INFO</level>
+                       <onMatch>ACCEPT</onMatch>
+                       <onMismatch>DENY</onMismatch>
+               </filter>
+               <file>${logDirectory}/rest/metrics.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/metrics.log.%d{yyyy-MM-dd}
+                       </fileNamePattern>
+               </rollingPolicy>
+               <encoder class="org.openecomp.aai.logging.EcompEncoder">
+                       <pattern>${eelfMetricLogPattern}</pattern>
+               </encoder>
+       </appender>
+       <appender name="asyncMETRIC" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>1000</queueSize>
+               <includeCallerData>true</includeCallerData>
+               <appender-ref ref="METRIC" />
+       </appender>
+
+       <appender name="DEBUG"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.LevelFilter">
+                       <level>DEBUG</level>
+                       <onMatch>ACCEPT</onMatch>
+                       <onMismatch>DENY</onMismatch>
+               </filter>
+               <file>${logDirectory}/rest/debug.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/debug.log.%d{yyyy-MM-dd}
+                       </fileNamePattern>
+               </rollingPolicy>
+               <encoder class="org.openecomp.aai.logging.EcompEncoder">
+                       <pattern>${eelfLogPattern}</pattern>
+               </encoder>
+       </appender>
+
+       <appender name="asyncDEBUG" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>1000</queueSize>
+               <includeCallerData>true</includeCallerData>
+               <appender-ref ref="DEBUG" />
+       </appender>
+
+       <appender name="ERROR"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>WARN</level>
+               </filter>
+               <file>${logDirectory}/rest/error.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/error.log.%d{yyyy-MM-dd}
+                       </fileNamePattern>
+               </rollingPolicy>
+               <encoder class="org.openecomp.aai.logging.EcompEncoder">
+                       <pattern>${eelfLogPattern}</pattern>
+               </encoder>
+       </appender>
+
+       <appender name="asyncERROR" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>1000</queueSize>
+               <includeCallerData>true</includeCallerData>
+               <appender-ref ref="ERROR" />
+       </appender>
+
+       <appender name="AUDIT"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <file>${logDirectory}/rest/audit.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/audit.log.%d{yyyy-MM-dd}
+                       </fileNamePattern>
+               </rollingPolicy>
+               <encoder class="org.openecomp.aai.logging.EcompEncoder">
+                       <pattern>${eelfAuditLogPattern}</pattern>
+               </encoder>
+       </appender>
+
+       <appender name="asyncAUDIT" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>1000</queueSize>
+               <includeCallerData>true</includeCallerData>
+               <appender-ref ref="AUDIT" />
+       </appender>
+
+       <appender name="translog"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.LevelFilter">
+                       <level>DEBUG</level>
+                       <onMatch>ACCEPT</onMatch>
+                       <onMismatch>DENY</onMismatch>
+               </filter>
+               <file>${logDirectory}/rest/translog.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/translog.log.%d{yyyy-MM-dd}
+                       </fileNamePattern>
+               </rollingPolicy>
+               <encoder class="org.openecomp.aai.logging.EcompEncoder">
+                       <pattern>${eelfLogPattern}</pattern>
+               </encoder>
+       </appender>
+       
+       <appender name="asynctranslog" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>1000</queueSize>
+               <includeCallerData>true</includeCallerData>
+               <appender-ref ref="translog" />
+       </appender>
+
+       <appender name="dmaapAAIEventConsumer"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>WARN</level>
+               </filter>
+               <File>${logDirectory}/dmaapAAIEventConsumer/error.log</File>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/error.log.%d{yyyy-MM-dd}
+                       </fileNamePattern>
+               </rollingPolicy>
+               <encoder class="org.openecomp.aai.logging.EcompEncoder">
+                       <pattern>${eelfLogPattern}</pattern>
+               </encoder>
+       </appender>
+
+       <appender name="dmaapAAIEventConsumerDebug"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.LevelFilter">
+                       <level>DEBUG</level>
+                       <onMatch>ACCEPT</onMatch>
+                       <onMismatch>DENY</onMismatch>
+               </filter>
+               <File>${logDirectory}/dmaapAAIEventConsumer/debug.log</File>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/debug.log.%d{yyyy-MM-dd}
+                       </fileNamePattern>
+               </rollingPolicy>
+               <encoder class="org.openecomp.aai.logging.EcompEncoder">
+                       <pattern>${eelfLogPattern}</pattern>
+               </encoder>
+       </appender>
+       <appender name="dmaapAAIEventConsumerMetric"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.LevelFilter">
+                       <level>INFO</level>
+                       <onMatch>ACCEPT</onMatch>
+                       <onMismatch>DENY</onMismatch>
+               </filter>
+               <File>${logDirectory}/dmaapAAIEventConsumer/metrics.log</File>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/metrics.log.%d{yyyy-MM-dd}
+                       </fileNamePattern>
+               </rollingPolicy>
+               <encoder class="org.openecomp.aai.logging.EcompEncoder">
+                       <pattern>${eelfLogPattern}</pattern>
+               </encoder>
+       </appender>
+
+       <!-- Spring related loggers -->
+       <logger name="org.springframework" level="WARN" />
+       <logger name="org.springframework.beans" level="WARN" />
+       <logger name="org.springframework.web" level="WARN" />
+       <logger name="com.blog.spring.jms" level="WARN" />
+
+       <!-- AJSC Services (bootstrap services) -->
+       <logger name="ajsc" level="WARN" />
+       <logger name="ajsc.RouteMgmtService" level="WARN" />
+       <logger name="ajsc.ComputeService" level="WARN" />
+       <logger name="ajsc.VandelayService" level="WARN" />
+       <logger name="ajsc.FilePersistenceService" level="WARN" />
+       <logger name="ajsc.UserDefinedJarService" level="WARN" />
+       <logger name="ajsc.UserDefinedBeansDefService" level="WARN" />
+       <logger name="ajsc.LoggingConfigurationService" level="WARN" />
+
+       <!-- AJSC related loggers (DME2 Registration, csi logging, restlet, servlet 
+               logging) -->
+       <logger name="ajsc.utils" level="WARN" />
+       <logger name="ajsc.utils.DME2Helper" level="WARN" />
+       <logger name="ajsc.filters" level="WARN" />
+       <logger name="ajsc.beans.interceptors" level="WARN" />
+       <logger name="ajsc.restlet" level="WARN" />
+       <logger name="ajsc.servlet" level="WARN" />
+       <logger name="com.att.ajsc" level="WARN" />
+       <logger name="com.att.ajsc.csi.logging" level="WARN" />
+       <logger name="com.att.ajsc.filemonitor" level="WARN" />
+
+       <!-- Other Loggers that may help troubleshoot -->
+       <logger name="net.sf" level="WARN" />
+       <logger name="org.apache.commons.httpclient" level="WARN" />
+       <logger name="org.apache.commons" level="WARN" />
+       <logger name="org.apache.coyote" level="WARN" />
+       <logger name="org.apache.jasper" level="WARN" />
+
+       <!-- Camel Related Loggers (including restlet/servlet/jaxrs/cxf logging. 
+               May aid in troubleshooting) -->
+       <logger name="org.apache.camel" level="WARN" />
+       <logger name="org.apache.cxf" level="WARN" />
+       <logger name="org.apache.camel.processor.interceptor" level="WARN" />
+       <logger name="org.apache.cxf.jaxrs.interceptor" level="WARN" />
+       <logger name="org.apache.cxf.service" level="WARN" />
+       <logger name="org.restlet" level="WARN" />
+       <logger name="org.apache.camel.component.restlet" level="WARN" />
+
+       <!-- logback internals logging -->
+       <logger name="ch.qos.logback.classic" level="WARN" />
+       <logger name="ch.qos.logback.core" level="WARN" />
+
+       <!-- logback jms appenders & loggers definition starts here -->
+       <appender name="auditLogs"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter" />
+               <file>${logDirectory}/perf-audit/Audit-${lrmRVer}-${lrmRO}-${Pid}.log
+               </file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+                       <fileNamePattern>${logDirectory}/perf-audit/Audit-${lrmRVer}-${lrmRO}-${Pid}.%i.log.zip
+                       </fileNamePattern>
+                       <minIndex>1</minIndex>
+                       <maxIndex>9</maxIndex>
+               </rollingPolicy>
+               <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize>
+               </triggeringPolicy>
+               <encoder>
+                       <pattern>"%d [%thread] %-5level %logger{1024} - %msg%n"</pattern>
+               </encoder>
+       </appender>
+       <appender name="perfLogs"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter" />
+               <file>${logDirectory}/perf-audit/Perform-${lrmRVer}-${lrmRO}-${Pid}.log
+               </file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+                       <fileNamePattern>${logDirectory}/perf-audit/Perform-${lrmRVer}-${lrmRO}-${Pid}.%i.log.zip
+                       </fileNamePattern>
+                       <minIndex>1</minIndex>
+                       <maxIndex>9</maxIndex>
+               </rollingPolicy>
+               <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize>
+               </triggeringPolicy>
+               <encoder>
+                       <pattern>"%d [%thread] %-5level %logger{1024} - %msg%n"</pattern>
+               </encoder>
+       </appender>
+       <if condition='property("JMS_BROKER").contains("WMQ")'>
+               <then>
+                       <appender name="Audit-Record-Queue" class="ajsc.JMSQueueAppender">
+                               <param name="InitialContextFactoryName" value="${JMS_WMQ_INITIAL_CONNECTION_FACTORY_NAME}" />
+                               <param name="ProviderURL" value="${JMS_WMQ_PROVIDER_URL}" />
+                               <param name="DestinationName" value="${JMS_WMQ_AUDIT_DESTINATION_NAME}" />
+                               <param name="ConnectionFactoryName" value="${JMS_WMQ_CONNECTION_FACTORY_NAME}" />
+                       </appender>
+                       <appender name="Performance-Tracker-Queue" class="ajsc.JMSQueueAppender">
+                               <param name="InitialContextFactoryName" value="${JMS_WMQ_INITIAL_CONNECTION_FACTORY_NAME}" />
+                               <param name="ProviderURL" value="${JMS_WMQ_PROVIDER_URL}" />
+                               <param name="DestinationName" value="${JMS_WMQ_PERF_DESTINATION_NAME}" />
+                               <param name="ConnectionFactoryName" value="${JMS_WMQ_CONNECTION_FACTORY_NAME}" />
+                       </appender>
+               </then>
+               <else>
+                       <!-- logback jms appenders definition starts here -->
+                       <appender name="Audit-Record-Queue" class="ajsc.JMSQueueAppender">
+                               <param name="InitialContextFactoryName"
+                                       value="com.tibco.tibjms.naming.TibjmsInitialContextFactory" />
+                               <param name="ProviderURL" value="${JMS_TIBCO_PROVIDER_URL}" />
+                               <param name="userName" value="${JMS_LOGGER_USER_NAME}" />
+                               <param name="password" value="${JMS_LOGGER_PASSWORD}" />
+                               <QueueBindingName>${JMS_LOGGER_AUDIT_QUEUE_BINDING}
+                               </QueueBindingName>
+                       </appender>
+                       <appender name="Performance-Tracker-Queue" class="ajsc.JMSQueueAppender">
+                               <param name="InitialContextFactoryName"
+                                       value="com.tibco.tibjms.naming.TibjmsInitialContextFactory" />
+                               <param name="ProviderURL" value="${JMS_TIBCO_PROVIDER_URL}" />
+                               <param name="userName" value="${JMS_LOGGER_USER_NAME}" />
+                               <param name="password" value="${JMS_LOGGER_PASSWORD}" />
+                               <QueueBindingName>${JMS_LOGGER_PERF_QUEUE_BINDING}
+                               </QueueBindingName>
+                       </appender>
+               </else>
+       </if>
+       <appender name="ASYNC-audit" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>1000</queueSize>
+               <includeCallerData>true</includeCallerData>
+               <discardingThreshold>0</discardingThreshold>
+               <appender-ref ref="Audit-Record-Queue" />
+       </appender>
+       <appender name="ASYNC-perf" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>1000</queueSize>
+               <includeCallerData>true</includeCallerData>
+               <discardingThreshold>0</discardingThreshold>
+               <appender-ref ref="Performance-Tracker-Queue" />
+       </appender>
+       <logger name="AuditRecord" level="INFO" additivity="false">
+               <appender-ref ref="ASYNC-audit" />
+               <appender-ref ref="auditLogs" />
+       </logger>
+       <logger name="AuditRecord_DirectCall" level="INFO" additivity="false">
+               <appender-ref ref="ASYNC-audit" />
+               <appender-ref ref="auditLogs" />
+       </logger>
+       <logger name="PerfTrackerRecord" level="INFO" additivity="false">
+               <appender-ref ref="ASYNC-perf" />
+               <appender-ref ref="perfLogs" />
+       </logger>
+       <!-- logback jms appenders & loggers definition ends here -->
+
+       <logger name="org.openecomp.aai.interceptors" level="DEBUG"
+               additivity="false">
+               <appender-ref ref="asynctranslog" />
+       </logger>
+
+       <logger name="org.openecomp.aai.interceptors.PreAaiAjscInterceptor" level="DEBUG">
+               <appender-ref ref="asyncAUDIT"/>
+       </logger>
+
+       <logger name="org.openecomp.aai.interceptors.PostAaiAjscInterceptor" level="DEBUG">
+               <appender-ref ref="asyncAUDIT"/>
+       </logger>
+
+       <logger name="org.openecomp.aai.dmaap" level="DEBUG" additivity="false">
+               <appender-ref ref="dmaapAAIEventConsumer" />
+               <appender-ref ref="dmaapAAIEventConsumerDebug" />
+               <appender-ref ref="dmaapAAIEventConsumerMetric" />
+       </logger>
+
+       <logger name="org.apache" level="WARN" />
+       <logger name="org.zookeeper" level="WARN" />
+       <logger name="com.thinkaurelius" level="WARN" />
+
+       <!-- ============================================================================ -->
+       <!-- General EELF logger -->
+       <!-- ============================================================================ -->
+       <logger name="com.att.eelf" level="WARN" additivity="false">
+               <appender-ref ref="asyncDEBUG" />
+               <appender-ref ref="asyncERROR" />
+               <appender-ref ref="asyncMETRIC" />
+       </logger>
+
+       <root level="DEBUG">
+               <appender-ref ref="asyncDEBUG" />
+               <appender-ref ref="asyncERROR" />
+               <appender-ref ref="asyncMETRIC" />
+               <appender-ref ref="asyncSANE" />
+       </root>
+</configuration>
diff --git a/aai-traversal/antBuild/build.xml b/aai-traversal/antBuild/build.xml
new file mode 100644 (file)
index 0000000..346380c
--- /dev/null
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+       <target name="runLocal">
+                <java dir="${basedir}" fork="yes" newenvironment="true"
+                        failonerror="true" classname="com.att.ajsc.runner.Runner">
+                        <classpath
+                                path="${classpath}:${basedir}/ajsc-shared-config/etc:${runAjscHome}/lib/ajsc-runner-${ajscRuntimeVersion}.jar" />
+
+                        <!-- Windows Users may need to add a jvmarg arg to create a temp directory 
+                                properly. -->
+                       <!-- <jvmarg value="-Djava.io.tmpdir=C:/yourTempDirectory"/>  -->
+
+                        <!-- Uncomment the following 2 jvmarg values to enable Remote Debugging. 
+                         -->
+                       <!-- <jvmarg value="-Xdebug" /> -->
+                        <!-- <jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5432" 
+                                /> -->
+
+                       <jvmarg value="-XX:MaxPermSize=512m" />
+                       <jvmarg value="-Xmx1024m" />
+
+                        <!-- Main ajsc Variables below (Variables necessary for proper startup 
+                                of AJSC) -->
+                       <env key="AJSC_HOME" value="${runAjscHome}" />
+                       <sysproperty key="AJSC_HOME" value="${runAjscHome}" />
+                        <!-- you may specify any external location for AJSC_CONF_HOME where etc 
+                                folder & all other configs can be found under it. If not specified, it will 
+                                default to AJSC_HOME -->
+                       <sysproperty key="AJSC_CONF_HOME" value="${basedir}/bundleconfig-local" />
+                       <sysproperty key="AJSC_SHARED_CONFIG" value="${basedir}/ajsc-shared-config" />
+                       
+                        <!-- Location of logback.xml file used for logging configurations. Please, 
+                                note, when deploying a service to either CSI or NON-CSI environment, this 
+                                system property will be set in sys-props.properties file. We are setting 
+                                it here for running locally due to the ease of use of maven variable for 
+                                basedir. -->
+                        <sysproperty key="logback.configurationFile"
+                                value="${basedir}/ajsc-shared-config/etc/logback.xml" />
+                       
+                        <!-- Setting system properties for the AJSC external libs and properties 
+                                folders below. When deploying to a node, these properties will be set within 
+                                the bundleconfig/etc/sysprops/sys-props.properties file. However, when running 
+                                locally, the ${basedir} substitution works more efficiently in this manner. -->
+                       <sysproperty key="AJSC_EXTERNAL_LIB_FOLDERS" value="${basedir}/target/commonLibs" />
+                        <sysproperty key="AJSC_EXTERNAL_PROPERTIES_FOLDERS"
+                                value="${basedir}/ajsc-shared-config/etc" />
+
+                        <!-- End of Main ajsc Variables below (Variables necessary for proper 
+                                startup of AJSC) -->
+
+                       <!-- Uncomment the following line to add oauthentication to your Service -->
+                       <!-- <sysproperty key="spring.profiles.active" value="oauth" /> -->
+
+                        <!-- If using Cassandra as Database, Enter the ip/host and port below 
+                                based on your known configuration -->
+                       <!-- <sysproperty key="cassandra.ip" value="hostname" /> -->
+                       <!-- <sysproperty key="cassandra.port" value="9042" /> -->
+
+                        <!-- The APP_SERVLET_URL_PATTERN variable is defaulted to "/services" 
+                                within the initial configuration of the AJSC. If you are changing the CamelServlet 
+                                Filter within the ajsc-override-web.xml, you should use that url-pattern 
+                                here. This is necessary to properly register your service with dme2. An empty 
+                                value, "", is used when NO value is wanted (url-pattern would be /* for CamelServlet 
+                                Filter) -->
+                       <!-- As of 4.5.1, this property is no longer needed -->
+                       <!-- <sysproperty key="APP_SERVLET_URL_PATTERN" value="/services" /> -->
+
+                       <!-- GRM/DME2 System Properties below -->
+                       <sysproperty key="AJSC_SERVICE_NAMESPACE" value="${module.ajsc.namespace.name}" />
+                       <sysproperty key="AJSC_SERVICE_VERSION" value="${module.ajsc.namespace.version}" />
+                       <sysproperty key="SOACLOUD_SERVICE_VERSION" value="${project.version}" />
+                       <!-- End of GRM/DME2 System Property Variables -->
+
+                       <!-- The following server.port variable was necessary for the proper registration 
+                                of the AJSC to dme2. This value may still need to be used if the Developer 
+                                is hardcoding their port (example: 8080). Then, the server.port value="8080". 
+                                The default functionality for the AJSC is to use EPHEMERAL ports. In this
+                                case, you do NOT need to set the server.port value. The AJSC will find the
+                                proper port value and register to dme2 correctly -->
+                       <!-- <sysproperty key="server.port" value="${serverPort}" /> -->
+
+                        <!-- Command Line Arguments to add to the java command. Here, you can 
+                                specify the port as well as the Context you want your service to run in. 
+                                Use context=/ to run in an unnamed Context (Root Context). The default configuration 
+                                of the AJSC is to run under the /ajsc Context. Setting the port here can 
+                                aid during the development phase of your service. However, you can leave 
+                                this argument out entirely, and the AJSC will default to using an Ephemeral 
+                                port. -->
+                       <arg line="context=/ port=${serverPort} sslport=${sslport}" />
+               </java>
+       </target>
+       <target name="prep_home_directory_for_swm_pkgcreate">
+
+<!-- ********* GENERATE CADI KEY AND ENCRYPTED PASSWORD ***********
+     
+            Uncomment the following if your cadi key get corrupted , It would 
+                        generate the Cadi key and password in the package phase and keep the key 
+                        in the 'src/main/config/ajscKey' and password in the bottom of cadi.properties(you 
+                        need to modify the 'aaf_pass' variable with this value . Plese modify the 
+                        template.cadi.properties as well before uploading to SOA node 
+-->
+
+<!-- 
+                <java jar="${basedir}/target/userjars/cadi-core-1.2.5.jar" fork="true"> 
+                <arg value="keygen" /> <arg value="src/main/config/ajscKey" /> 
+                </java> 
+                
+                <echo>***Cadi Key file generated ****</echo> 
+                
+                <java jar="${basedir}/target/userjars/cadi-core-1.2.5.jar" 
+                fork="true" append="true" output="${basedir}/src/main/config/cadi.properties"> 
+                <arg value="digest" /> <arg value="ajscRocks!" /> <arg value="src/main/config/ajscKey" 
+                /> 
+                </java> 
+                
+-->
+
+
+
+               <!-- These tasks are copying contents from the installHomeDirectory into 
+                       the eventual $AJSC_HOME directory for running locally and soa cloud installation -->
+               <echo message="ENTERING 'prep_home_directory_for_swm_pkgcreate' ant tasks" />
+
+                <!-- Please, NOTE: The ajsc-archetype is setup for a default CSI Env deployment. 
+                        If you are deploying to a CSI Env, you should NOT have to change anything 
+                        within this build file. However, if you are NOT deploying to a CSI Env, you 
+                        should comment OUT the CSI related portion of this build.xml. -->
+
+                <!-- The following code snippet is copying the bundleconfig-csi directory 
+                        to the proper installation/bundleconfig directory used in CSI envs. If you 
+                        are NOT installing to a CSI node, you should comment out (or delete) the 
+                        following snippet, and uncomment the NON-CSI copy task to copy EVERYTHING 
+                        to the installation/bundleconfig directory. -->
+
+                <!-- CSI related bundleconfig copy task. If you are NOT deploying to a 
+                        CSI Env, please COMMENT OUT or delete the following copy task code snippet. -->
+                <!--<copy toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/bundleconfig" 
+                        failonerror="true"> <fileset dir="${basedir}/bundleconfig-csi" /> </copy> -->
+               <!-- End of CSI related bundleconfig copy task -->
+
+                <!-- NOTE: If you are NOT deploying to CSI environment, and you are NOT 
+                        using an AJSC_SHARED_CONFIG location on a node, you should go ahead and copy 
+                        EVERYTHING from bundleconfig and ajsc-shared-config (logback.xml) directory 
+                        to utilize proper logging from logback.xml. Simply, uncomment the following 
+                        code snippet below to copy EVERYTHING and comment out the CSI related build 
+                        script above. -->
+                <!-- NON-CSI related build copy task. Please, uncomment the following code 
+                        snippet to deploy the proper artifacts to a NON-CSI Env. -->
+                <copy
+                               toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/bundleconfig"
+                               failonerror="true">
+                               <fileset dir="${basedir}/bundleconfig-local" includes="**/**" />
+                       </copy>
+                <copy
+                        toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/bundleconfig/etc"
+                        failonerror="true">
+                               <fileset dir="${basedir}/ajsc-shared-config/etc" includes="**/**" />
+                       </copy> 
+               <!-- End of NON-CSI related build copy task. -->
+
+               <!-- Copying any zips (deployment packages) to $AJSC_HOME/services for 
+                       auto-deployment -->
+                <copy
+                        toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/services"
+                        failonerror="false">
+                       <fileset dir="${basedir}/services" includes="*.zip" />
+               </copy>
+
+                <!-- Copying runtimeEnvironment zip file to $AJSC_HOME/runtime and renaming 
+                        runtimeEnvironment.zip for proper auto-deployment of ajsc services. -->
+               <!--               <copy
+                        tofile="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/runtime/runtimeEnvironment.zip">
+                       <fileset dir="target" includes="*-runtimeEnvironment.zip" />
+               </copy>
+-->
+               <!-- Copying dependencies from the service project (not provided by AJSC 
+                       Container) to the $AJSC_HOME/extJars folder to be accessible on the classpath -->
+                <copy
+                        toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/extJars"
+                        failonerror="false">
+                       <fileset dir="target/userjars" includes="*" />
+               </copy>
+
+               <!-- extApps directory MUST be created for ajsc-runner to run correctly, 
+                       even if empty. DO NOT REMOVE!!! -->
+                <!-- extApps directory created to deploy other war files on startup or 
+                        hot deploy War files after ajsc starts up. -->
+                <mkdir
+                        dir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/extApps" />
+
+               <!-- Copying any extra wars to $AJSC_HOME/extApps to be deployed within 
+                       AJSC -->
+                <copy
+                        toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/extApps"
+                        failonerror="false">
+                        <fileset dir="${basedir}/src/main/resources/extApps"
+                                includes="*" />
+               </copy>
+
+                <!-- staticContent folder is for serving static content within an ajsc 
+                        service. Any static content to be served will be copyied to the ultimate 
+                        $AJSC_HOME/staticContent folder and can be served with the  
+                        camel component. -->
+                <!-- Uncomment the following snippet to copy items from staticContent folder 
+                        to ultimate $AJSC_HOME/staticConent -->
+                <!-- <copy toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/staticContent" 
+                        failonerror="false"> <fileset dir="${basedir}/staticContent" includes="**/**" 
+                        /> </copy> -->
+
+                <!-- Copying extra jar files that have been labeled as dependencies in 
+                        service project to /extJars folder to be made available on the classpath 
+                        for your service -->
+                <copy
+                        toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/extJars"
+                        failonerror="false">
+                       <fileset dir="target" includes="*.jar" />
+               </copy>
+
+                <!-- Copying deployment packages created within the project to the $AJSC_HOME/services 
+                        folder to be auto deployed. -->
+                <copy
+                        toDir="${basedir}/target/swm/package/nix/dist_files${distFilesRoot}/services">
+                       <fileset dir="target" includes="*.zip" excludes="*-runtimeEnvironment.zip" />
+               </copy>
+
+               <echo message="EXITING 'prep_assembly_output_for_swm_plugin' ant tasks" />
+       </target>
+</project>
diff --git a/aai-traversal/bundleconfig-csi/etc/appprops/app-intercepts.properties b/aai-traversal/bundleconfig-csi/etc/appprops/app-intercepts.properties
new file mode 100644 (file)
index 0000000..3230921
--- /dev/null
@@ -0,0 +1,6 @@
+#This is where all your application intercept strategies must be configured. AJSC reads this property file and adds
+#the list of intercepts specified here to the camel context. This can be useful for accessing every exchange object transferred from/to
+#each endpoint in the request/response flow and can allow for more precise debugging and/or processing of the exchange. 
+
+#e.g. 
+#intercepts=org.openecomp.aai.ajsc_aai.JaxrsEchoService,packagename.class1name,packagename.class2name
diff --git a/aai-traversal/bundleconfig-local/README.txt b/aai-traversal/bundleconfig-local/README.txt
new file mode 100644 (file)
index 0000000..a915213
--- /dev/null
@@ -0,0 +1,9 @@
+The bundleconfig-local directory contains the necessary configuration files to be used for running locally. When running 
+locally, the "mvn -P runLocal" or the "mvn -P runAjsc" profiles will be using this bundleconfig-local directory as the AJSC_CONF
+directory. When deploying to a CSI env, the bundleconfig-csi directory will be copied to the ultimate installation/bundleconfig 
+directory and will be used for your AJSC service once installed. If you are not deploying to a CSI env, please look at the 
+antBuild/build.xml file for help in some simple copying of the appropriate folders/files for a NON-CSI env. 
+
+The ajsc-shared-config directory houses the shared configurations that will be used in CSI envs. This includes the logging 
+functionality of the logback.xml and some csm related artifacts that may be necessary to use while running locally.
+When running locally, the system property, "AJSC_SHARED_CONFIG", will point to this location to utilize the logback.xml.
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/RELEASE_NOTES.txt b/aai-traversal/bundleconfig-local/RELEASE_NOTES.txt
new file mode 100644 (file)
index 0000000..a567d9b
--- /dev/null
@@ -0,0 +1 @@
+Place Release Notes here to provide updated Release information for CSTEM to better help manage your service in the CSI environment.
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/Introscope.properties b/aai-traversal/bundleconfig-local/etc/appprops/Introscope.properties
new file mode 100644 (file)
index 0000000..319381e
--- /dev/null
@@ -0,0 +1,8 @@
+#CSI environment uses the Introscope java agent for monitoring services. The AJSC has provided an implementation class that
+#provides basic information to the Introscope Enterprise Manager for each http request/response. 
+
+introscopeEventClass=com.att.ajsc.introscope.IntroscopeEventNotifierImpl
+serviceName=N/A
+conversationId=N/A
+uniqueID=N/A
+userID=N/A
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/PostProcessorInterceptors.properties b/aai-traversal/bundleconfig-local/etc/appprops/PostProcessorInterceptors.properties
new file mode 100644 (file)
index 0000000..f4fed40
--- /dev/null
@@ -0,0 +1,3 @@
+#This properties file is for defining any PostProcessorInterceptors that have been created for your AJSC service.
+
+/**=ajsc.beans.interceptors.CsiPostInterceptor,org.openecomp.aai.interceptors.PostAaiAjscInterceptor
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/PreProcessorInterceptors.properties b/aai-traversal/bundleconfig-local/etc/appprops/PreProcessorInterceptors.properties
new file mode 100644 (file)
index 0000000..a6dfe01
--- /dev/null
@@ -0,0 +1,3 @@
+#This properties file is for defining any PreProcessorInterceptors that have been created for your AJSC service.
+
+/**=com.att.ajsc.csi.restmethodmap.RestMethodMapInterceptor,ajsc.beans.interceptors.CsiPreInterceptor,org.openecomp.aai.interceptors.PreAaiAjscInterceptor
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/aaiEventDMaaPPublisher.properties b/aai-traversal/bundleconfig-local/etc/appprops/aaiEventDMaaPPublisher.properties
new file mode 100644 (file)
index 0000000..1c2a6bf
--- /dev/null
@@ -0,0 +1,28 @@
+TransportType=DME2
+Latitude=39.099727
+Longitude=-94.578567
+Version=1.0
+ServiceName=ONAPserverTBD
+Environment=TEST
+routeOffer=MR1SBKCD
+SubContextPath=/
+Protocol=http
+MethodType=POST
+username=ONAPserverTBD
+password=
+contenttype=application/json
+host=ONAPserverTBD
+topic=AAI-EVENT
+partition=AAI
+maxBatchSize=100
+maxAgeMs=250
+AFT_DME2_EXCHANGE_REQUEST_HANDLERS=ONAPserverTBD
+AFT_DME2_EXCHANGE_REPLY_HANDLERS=ONAPserverTBD
+AFT_DME2_REQ_TRACE_ON=true
+AFT_ENVIRONMENT=AFTUAT
+AFT_DME2_EP_CONN_TIMEOUT=15000
+AFT_DME2_ROUNDTRIP_TIMEOUT_MS=240000
+AFT_DME2_EP_READ_TIMEOUT_MS=50000
+sessionstickinessrequired=NO
+DME2preferredRouterFilePath=preferredRoute.txt
+MessageSentThreadOccurance=50
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/aaiconfig.properties b/aai-traversal/bundleconfig-local/etc/appprops/aaiconfig.properties
new file mode 100644 (file)
index 0000000..a24c341
--- /dev/null
@@ -0,0 +1,82 @@
+####################################################################
+#  REMEMBER TO THINK ABOUT ENVIRONMENTAL DIFFERENCES AND CHANGE THE
+#  TEMPLATE AND *ALL* DATAFILES
+####################################################################
+
+aai.config.checktime=1000
+
+# this could come from siteconfig.pl?
+aai.config.nodename=AutomaticallyOverwritten
+
+aai.logging.hbase.interceptor=true
+aai.logging.hbase.enabled=true
+aai.logging.hbase.logrequest=true
+aai.logging.hbase.logresponse=true
+
+aai.logging.trace.enabled=true
+aai.logging.trace.logrequest=false
+aai.logging.trace.logresponse=false
+
+aai.transaction.logging=true
+aai.transaction.logging.get=true
+aai.transaction.logging.post=true
+
+aai.server.url.base=https://localhost:8446/aai/
+aai.server.url=https://localhost:8446/aai/v10/
+aai.global.callback.url=https://localhost:8446/aai/
+
+aai.auth.cspcookies_on=false
+aai.dbmodel.filename=ex5.json
+aai.truststore.filename=aai_keystore
+aai.truststore.passwd.x=OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0
+aai.keystore.filename=aai-client-cert.p12
+aai.keystore.passwd.x=
+
+# for transaction log
+hbase.table.name=aailogging-dev1.dev
+hbase.notificationTable.name=aainotification-dev1.dev
+hbase.table.timestamp.format=YYYYMMdd-HH:mm:ss:SSS
+hbase.zookeeper.quorum=ONAPserverTBD
+hbase.zookeeper.property.clientPort=2181
+hbase.zookeeper.znode.parent=/hbase
+
+
+# single primary server
+aai.primary.filetransfer.serverlist=ONAPserverTBD
+aai.primary.filetransfer.primarycheck=echo:8443/aai/util/echo
+aai.primary.filetransfer.pingtimeout=5000
+aai.primary.filetransfer.pingcount=5
+
+
+#rsync properties
+aai.rsync.command=rsync
+aai.rsync.options.list=-v|-t
+aai.rsync.remote.user=aaiadmin
+aai.rsync.enabled=y
+
+aai.notification.current.version=v10
+aai.notificationEvent.default.status=UNPROCESSED
+aai.notificationEvent.default.eventType=AAI-EVENT
+aai.notificationEvent.default.domain=devINT1
+aai.notificationEvent.default.sourceName=aai
+aai.notificationEvent.default.sequenceNumber=0
+aai.notificationEvent.default.severity=NORMAL
+aai.notificationEvent.default.version=v10
+# This one lets us enable/disable resource-version checking on updates/deletes
+aai.resourceversion.enableflag=true
+aai.logging.maxStackTraceEntries=10
+aai.default.api.version=v10
+
+# Used by Model-processing code
+aai.model.delete.sleep.per.vtx.msec=500
+aai.model.query.resultset.maxcount=50
+aai.model.query.timeout.sec=90
+aai.model.proc.max.levels=50
+aai.edgeTag.proc.max.levels=50
+
+aai.dmaap.workload.enableEventProcessing=true
+
+aai.realtime.clients=RO,SDNC,MSO
+
+aai.server.rebind=g
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/app-intercepts.properties b/aai-traversal/bundleconfig-local/etc/appprops/app-intercepts.properties
new file mode 100644 (file)
index 0000000..3230921
--- /dev/null
@@ -0,0 +1,6 @@
+#This is where all your application intercept strategies must be configured. AJSC reads this property file and adds
+#the list of intercepts specified here to the camel context. This can be useful for accessing every exchange object transferred from/to
+#each endpoint in the request/response flow and can allow for more precise debugging and/or processing of the exchange. 
+
+#e.g. 
+#intercepts=org.openecomp.aai.ajsc_aai.JaxrsEchoService,packagename.class1name,packagename.class2name
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/caet.properties b/aai-traversal/bundleconfig-local/etc/appprops/caet.properties
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/default-logback.xml b/aai-traversal/bundleconfig-local/etc/appprops/default-logback.xml
new file mode 100644 (file)
index 0000000..0dc841d
--- /dev/null
@@ -0,0 +1,20 @@
+<configuration debug="false">
+       <property name="defaultPattern" value="%d{MM/dd-HH:mm:ss.SSS}|%logger|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}|%X{Timer}|%msg%n" />
+
+       <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+               <encoder>
+                       <pattern>${defaultPattern}</pattern>
+               </encoder>
+       </appender>
+
+       <logger name="org.reflections" level="WARN"/>
+       <logger name="org.apache.zookeeper" level="WARN"/>
+       <logger name="org.apache.hadoop" level="WARN"/>
+       <logger name="com.thinkaurelius" level="WARN"/>
+       <logger name="ch.qos.logback.classic" level="WARN" />
+       <logger name="ch.qos.logback.core" level="WARN" />
+
+       <root level="INFO">
+               <appender-ref ref="STDOUT"/>
+       </root>
+</configuration>
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/error.properties b/aai-traversal/bundleconfig-local/etc/appprops/error.properties
new file mode 100644 (file)
index 0000000..11416ca
--- /dev/null
@@ -0,0 +1,164 @@
+# Adding comment trying to trigger a build
+#-------------------------------------------------------------------------------                                                                                            ----------
+#Key=Disposition:Category:Severity:Error Code:HTTP ResponseCode:RESTError Code:Error Message
+#-------------------------------------------------------------------------------                                                                                            ----------
+# testing code, please don't change unless error utility source code changes
+AAI_TESTING=5:2:WARN:0000:400:0001:Error code for testing
+
+# General success
+AAI_0000=0:0:INFO:0000:200:0000:Success
+
+# health check success
+AAI_0001=0:0:INFO:0001:200:0001:Success X-FromAppId=%1 X-TransactionId=%2 
+AAI_0002=0:0:INFO:0002:200:0001:Successful health check
+
+# Success with additional info
+AAI_0003=0:3:INFO:0003:202:0003:Success with additional info performing %1 on %2. Added %3 with key %4
+AAI_0004=0:3:INFO:0004:202:0003:Added prerequisite object to db
+
+#--- aairest: 3000-3299
+# svc errors
+AAI_3000=5:2:INFO:3000:400:3000:Invalid input performing %1 on %2
+AAI_3001=5:6:INFO:3001:404:3001:Resource not found for %1 using id %2
+AAI_3002=5:1:WARN:3002:400:3002:Error writing output performing %1 on %2
+AAI_3003=5:1:WARN:3003:400:3003:Failed to make edge to missing target node of type %3 with keys %4 performing %1 on %2
+AAI_3005=5:6:WARN:3005:404:3001:Node cannot be directly accessed for read, must be accessed via ancestor(s)
+AAI_3006=5:6:WARN:3006:404:3001:Node cannot be directly accessed for write, must be accessed via ancestor(s)
+AAI_3007=5:6:INFO:3007:410:3007:This version (%1) of the API is retired, please migrate to %2
+AAI_3008=5:6:ERROR:3008:400:3008:URI is not encoded in UTF-8
+AAI_3009=5:6:ERROR:3009:400:3002:Malformed URL
+# pol errors
+AAI_3100=5:1:WARN:3100:400:3100:Unsupported operation %1
+AAI_3101=5:1:WARN:3101:403:3101:Attempt by client %1 to execute API %2
+AAI_3102=5:1:WARN:3102:400:3102:Error parsing input performing %1 on %2
+AAI_3300=5:1:WARN:3300:403:3300:Unauthorized
+AAI_3301=5:1:WARN:3301:401:3301:Stale credentials
+AAI_3302=5:1:WARN:3302:401:3301:Not authenticated
+AAI_3303=5:1:ERROR:3303:403:3300:Too many objects would be returned by this request, please refine your request and retry
+
+#--- aaigen: 4000-4099
+AAI_4000=5:4:ERROR:4000:500:3002:Internal Error
+AAI_4001=5:4:FATAL:4001:500:3002:Configuration file not found
+AAI_4002=5:4:FATAL:4002:500:3002:Error reading Configuration file
+AAI_4003=5:4:ERROR:4003:500:3002:Error writing to log file
+AAI_4004=5:4:FATAL:4004:500:3002:Error reading/parsing the error properties file
+AAI_4005=5:4:FATAL:4005:500:3002:Missing or invalid configuration parameter
+AAI_4006=5:4:FATAL:4006:500:3002:Unexpected error in service
+AAI_4007=5:4:ERROR:4007:500:3102:Input parsing error
+AAI_4008=5:4:ERROR:4008:500:3002:Output parsing error
+AAI_4009=4:0:ERROR:4009:400:3000:Invalid X-FromAppId in header
+AAI_4010=4:0:ERROR:4010:400:3000:Invalid X-TransactionId in header
+AAI_4011=5:4:ERROR:4011:500:3002:Missing data for REST error response
+AAI_4012=5:4:ERROR:4012:500:3002:Bad rule data in RestRules 
+AAI_4013=5:4:ERROR:4013:500:3002:Error connecting to AAI REST API
+AAI_4014=4:0:ERROR:4014:400:3000:Invalid Accept header
+AAI_4015=4:0:ERROR:4015:400:3000:You must provide at least one indexed property
+AAI_4016=4:0:ERROR:4016:400:3000:The depth parameter must be a number or the string "all"
+AAI_4017=5:2:INFO:4017:400:3000:Could not set property
+AAI_4018=5:2:ERROR:4018:400:3000:Unable to convert the string to integer
+#--- aaidbmap: 5101-5199
+AAI_5101=5:4:FATAL:5101:500:3002:Could not connect to database
+AAI_5102=5:4:FATAL:5102:500:3002:Graph database is null after open
+AAI_5103=5:4:ERROR:5103:500:3002:Unexpected error during commit
+AAI_5104=5:4:ERROR:5104:500:3002:Unexpected error during rollback
+AAI_5105=5:4:ERROR:5105:500:3002:Unexpected error reading/updating database
+AAI_5106=5:4:WARN:5106:404:3001:Node not found
+AAI_5107=5:2:WARN:5107:400:3000:Required information missing
+AAI_5108=5:2:WARN:5108:200:0:Unexpected information in request being ignored
+
+#--- aaidbgen: 6101-6199
+AAI_6101=5:4:ERROR:6101:500:3002:null TitanGraph object passed
+AAI_6102=5:4:WARN:6102:400:3000:Passed-in property is not valid for this nodeType
+AAI_6103=5:4:WARN:6103:400:3000:Required Node-property not found in input data
+AAI_6104=5:4:WARN:6104:400:3000:Required Node-property was passed with no data
+AAI_6105=5:4:WARN:6105:400:3000:Node-Key-Property not defined in DbMaps
+AAI_6106=5:4:WARN:6106:400:3000:Passed-in property is not valid for this edgeType
+AAI_6107=5:4:WARN:6107:400:3000:Required Edge-property not found in input data
+AAI_6108=5:4:WARN:6108:400:3000:Required Edge-property was passed with no data
+AAI_6109=5:4:WARN:6109:400:3000:Bad dependent Node value
+AAI_6110=5:4:ERROR:6110:400:3100:Node cannot be deleted
+AAI_6111=5:4:ERROR:6111:400:3000:JSON processing error
+AAI_6112=5:4:ERROR:6112:400:3000:More than one node found by getUniqueNode()
+AAI_6114=5:4:INFO:6114:404:3001:Node Not Found
+AAI_6115=5:4:ERROR:6115:400:3000:Unrecognized NodeType
+AAI_6116=5:4:ERROR:6116:400:3000:Unrecognized Property
+AAI_6117=5:4:ERROR:6117:400:3000:Uniqueness constraint violated
+AAI_6118=5:4:ERROR:6118:400:3000:Required Field not passed.
+AAI_6120=5:4:ERROR:6120:400:3000:Bad Parameter Passed
+AAI_6121=5:4:ERROR:6121:400:3000:Problem with internal AAI reference data
+AAI_6122=5:4:ERROR:6122:400:3000:Data Set not complete in DB for this request
+AAI_6123=5:4:ERROR:6123:500:3000:Bad Data found by DataGrooming Tool - Investigate
+AAI_6124=5:4:ERROR:6124:500:3000:File read/write error
+AAI_6125=5:4:WARN:6125:500:3000:Problem Pulling Data Set
+AAI_6126=5:4:ERROR:6126:400:3000:Edge cannot be deleted
+AAI_6127=5:4:INFO:6127:404:3001:Edge Not Found
+AAI_6128=5:4:INFO:6128:500:3000:Unexpected error
+AAI_6129=5:4:INFO:6129:404:3003:Error making edge to target node
+AAI_6130=5:4:WARN:6130:412:3000:Precondition Required
+AAI_6131=5:4:WARN:6131:412:3000:Precondition Failed
+AAI_6132=5:4:WARN:6132:400:3000:Bad Model Definition 
+AAI_6133=5:4:WARN:6133:400:3000:Bad Named Query Definition
+AAI_6134=5:4:ERROR:6134:500:6134:Could not persist transaction to storage back end. Exhausted retry amount
+AAI_6135=5:4:WARN:6135:412:3000:Resource version specified on create
+AAI_6136=5:4:ERROR:6136:400:3000:Object cannot hold multiple items
+AAI_6137=5:4:ERROR:6137:400:3000:Cannot perform writes on multiple vertices
+AAI_6138=5:4:ERROR:6138:400:3000:Cannot delete multiple vertices
+AAI_6139=5:4:ERROR:6139:404:3000:Attempted to add edge to vertex that does not exist
+AAI_6140=5:4:ERROR:6140:400:3000:Edge multiplicity violated
+AAI_6141=5:4:WARN:6141:400:3000:Please Refine Query
+AAI_6142=5:4:INFO:6142:400:3000:Retrying transaction
+AAI_6143=5:4:INFO:6143:400:3000:Ghost vertex found
+AAI_6144=5:4:WARN:6144:400:3000:Cycle found in graph
+AAI_6145=5:4:ERROR:6145:400:3000:Cannot create a nested/containment edge via relationship
+AAI_6146=5:4:ERROR:6146:400:3000:Ambiguous identity map found, use a URI instead
+
+#--- aaicsvp: 7101-7199
+AAI_7101=5:4:ERROR:7101:500:3002:Unexpected error in CSV file processing
+AAI_7102=5:4:ERROR:7102:500:3002:Error in cleanup temporary directory
+#AAI_7103=4:2:ERROR:7103:500:3002:Unsupported user
+AAI_7104=5:4:ERROR:7104:500:3002:Failed to create directory
+AAI_7105=5:4:ERROR:7105:500:3002:Temporary directory exists
+AAI_7106=5:4:ERROR:7106:500:3002:Cannot delete
+AAI_7107=5:4:ERROR:7107:500:3002:Input file does not exist
+AAI_7108=5:4:ERROR:7108:500:3002:Output file does not exist
+AAI_7109=5:4:ERROR:7109:500:3002:Error closing file
+AAI_7110=5:4:ERROR:7110:500:3002:Error loading/reading properties file
+AAI_7111=5:4:ERROR:7111:500:3002:Error executing shell script
+AAI_7112=5:4:ERROR:7112:500:3002:Error creating output file
+AAI_7113=5:4:ERROR:7113:500:3002:Trailer record error
+AAI_7114=5:4:ERROR:7114:500:3002:Input file error
+AAI_7115=5:4:ERROR:7115:500:3002:Unexpected error
+AAI_7116=5:4:ERROR:7116:500:3002:Request error 
+AAI_7117=5:4:ERROR:7117:500:3002:Error in get http client object
+AAI_7118=5:4:ERROR:7118:500:3002:Script Error
+AAI_7119=5:4:ERROR:7119:500:3002:Unknown host
+
+#--- aaisdnc: 7201-7299
+AAI_7202=5:4:ERROR:7202:500:3002:Error getting connection to odl
+AAI_7203=5:4:ERROR:7203:500:3002:Unexpected error calling DataChangeNotification API
+AAI_7204=5:4:ERROR:7204:500:3002:Error returned by DataChangeNotification API
+AAI_7205=5:4:ERROR:7205:500:3002:Unexpected error running notifySDNCOnUpdate
+AAI_7206=5:4:ERROR:7206:500:3002:Invalid data returned from ODL
+
+#--- NotificationEvent, using UEB space
+AAI_7350=5:4:ERROR:7305:500:3002:Notification event creation failed
+
+#--- aairestctlr: 7401-7499
+AAI_7401=5:4:ERROR:7401:500:3002:Error connecting to AAI REST API
+AAI_7402=5:4:ERROR:7402:500:3002:Unexpected error
+AAI_7403=5:4:WARN:7403:400:3001:Request error
+AAI_7404=5:4:INFO:7404:404:3001:Node not found
+
+#--- aaiauth: 9101-9199
+AAI_9101=5:0:WARN:9101:403:3300:User is not authorized to perform function
+AAI_9102=5:0:WARN:9102:401:3301:Refresh credentials from source
+AAI_9103=5:0:WARN:9103:403:3300:User not found
+AAI_9104=5:0:WARN:9104:401:3302:Authentication error
+AAI_9105=5:0:WARN:9105:403:3300:Authorization error
+AAI_9106=5:0:WARN:9106:403:3300:Invalid AppId
+#AAI_9107=5:0:WARN:9107:403:3300:No Username in Request
+AAI_9107=5:0:WARN:9107:403:3300:SSL is not provided in request, please contact admin
+
+#--- aaiinstar: 9201-9299
+AAI_9201=5:4:ERROR:9201:500:3002:Unable to send notification
+AAI_9202=5:4:ERROR:9202:500:3002:Unable to start a thread
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/gremlin-server-config.yaml b/aai-traversal/bundleconfig-local/etc/appprops/gremlin-server-config.yaml
new file mode 100644 (file)
index 0000000..19caebd
--- /dev/null
@@ -0,0 +1,3 @@
+hosts: [localhost]
+port: 8182
+serializer: { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0 }
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/logging.properties b/aai-traversal/bundleconfig-local/etc/appprops/logging.properties
new file mode 100644 (file)
index 0000000..e029cc4
--- /dev/null
@@ -0,0 +1,128 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+# this is where we will limit logging on components
+org.apache.hadoop.level=WARNING
+org.apache.zookeeper.level=WARNING
+org.reflections.level=WARNING
+com.thinkaurelius.level=WARNING
+
+1catalina.org.apache.juli.FileHandler.level = FINE
+1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+1catalina.org.apache.juli.FileHandler.prefix = catalina.
+
+2localhost.org.apache.juli.FileHandler.level = FINE
+2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+2localhost.org.apache.juli.FileHandler.prefix = localhost.
+
+3manager.org.apache.juli.FileHandler.level = FINE
+3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+3manager.org.apache.juli.FileHandler.prefix = manager.
+
+4host-manager.org.apache.juli.FileHandler.level = FINE
+4host-manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+4host-manager.org.apache.juli.FileHandler.prefix = host-manager.
+
+java.util.logging.ConsoleHandler.level = INFO
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler
+
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
+org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.FileHandler
+
+# For example, set the org.apache.catalina.util.LifecycleBase logger to log
+# each component that extends LifecycleBase changing state:
+#org.apache.catalina.util.LifecycleBase.level = FINE
+
+# To see debug messages in TldLocationsCache, uncomment the following line:
+#org.apache.jasper.compiler.TldLocationsCache.level = FINE
+
+
+################################
+# OpenEJB/TomEE specific loggers
+################################
+#
+# ACTIVATE LEVEL/HANDLERS YOU WANT
+# IF YOU ACTIVATE 5tomee.org.apache.juli.FileHandler
+# ADD IT TO handlers LINE LIKE:
+#
+# handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4host-manager.org.apache.juli.FileHandler, 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+#
+# LEVELS:
+# =======
+#
+# OpenEJB.level             = WARNING
+# OpenEJB.options.level     = INFO
+# OpenEJB.server.level      = INFO
+# OpenEJB.startup.level     = INFO
+# OpenEJB.startup.service.level = WARNING
+# OpenEJB.startup.config.level = INFO
+# OpenEJB.hsql.level        = INFO
+# CORBA-Adapter.level       = WARNING
+# Transaction.level         = WARNING
+# org.apache.activemq.level = SEVERE
+# org.apache.geronimo.level = SEVERE
+# openjpa.level             = WARNING
+# OpenEJB.cdi.level         = INFO
+# org.apache.webbeans.level = INFO
+# org.apache.openejb.level = FINE
+#
+# HANDLERS:
+# =========
+#
+# OpenEJB.handlers             = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# OpenEJB.options.handlers     = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# OpenEJB.server.handlers      = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# OpenEJB.startup.handlers     = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# OpenEJB.startup.service.handlers = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# OpenEJB.startup.config.handlers = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# OpenEJB.hsql.handlers        = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# CORBA-Adapter.handlers       = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# Transaction.handlers         = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# org.apache.activemq.handlers = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# org.apache.geronimo.handlers = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# openjpa.handlers             = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# OpenEJB.cdi.handlers         = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# org.apache.webbeans.handlers = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+# org.apache.openejb.handlers = 5tomee.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
+#
+# TOMEE HANDLER SAMPLE:
+# =====================
+#
+# 5tomee.org.apache.juli.FileHandler.level = FINEST
+# 5tomee.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+# 5tomee.org.apache.juli.FileHandler.prefix = tomee.
+
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/methodMapper.properties b/aai-traversal/bundleconfig-local/etc/appprops/methodMapper.properties
new file mode 100644 (file)
index 0000000..d6c1158
--- /dev/null
@@ -0,0 +1,24 @@
+{
+    "ActiveAndAvailableInventory-Traversal" : [{
+            "logicalName" : "getAAIResource",
+            "method" : "get",
+            "url" : "/aai/*"
+        }, {
+            "logicalName" : "putAAIResource",
+            "method" : "put",
+            "url" : "/aai/*"
+        }, {
+            "logicalName" : "deleteAAIResource",
+            "method" : "delete",
+            "url" : "/aai/*"
+        }, {
+            "logicalName" : "postAAIResource",
+            "method" : "post",
+            "url" : "/aai/*"
+        }, {
+            "logicalName" : "patchAAIResource",
+            "method" : "patch",
+            "url" : "/aai/*"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/preferredRoute.txt b/aai-traversal/bundleconfig-local/etc/appprops/preferredRoute.txt
new file mode 100644 (file)
index 0000000..662b0aa
--- /dev/null
@@ -0,0 +1 @@
+preferredRouteKey=MR1
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/titan-cached.properties b/aai-traversal/bundleconfig-local/etc/appprops/titan-cached.properties
new file mode 100644 (file)
index 0000000..0a3403f
--- /dev/null
@@ -0,0 +1,18 @@
+query.fast-property=true
+# the following parameters are not reloaded automatically and require a manual bounce
+#storage.backend=inmemory
+storage.backend=inmemory
+storage.hostname=localhost
+
+#schema.default=none
+storage.lock.wait-time=300
+storage.hbase.table=aaigraph-dev02
+storage.hbase.ext.zookeeper.znode.parent=/hbase
+#caching on
+cache.db-cache = true
+cache.db-cache-clean-wait = 20
+cache.db-cache-time = 180000
+cache.db-cache-size = 0.3
+
+#load graphson file on startup
+load.snapshot.file=false
diff --git a/aai-traversal/bundleconfig-local/etc/appprops/titan-realtime.properties b/aai-traversal/bundleconfig-local/etc/appprops/titan-realtime.properties
new file mode 100644 (file)
index 0000000..989f3be
--- /dev/null
@@ -0,0 +1,15 @@
+query.fast-property=true
+# the following parameters are not reloaded automatically and require a manual bounce
+#storage.backend=inmemory
+storage.backend=inmemory
+storage.hostname=localhost
+
+#schema.default=none
+storage.lock.wait-time=300
+storage.hbase.table=aaigraph-dev02
+storage.hbase.ext.zookeeper.znode.parent=/hbase
+# Setting db-cache to false ensure the fastest propagation of changes across servers
+cache.db-cache = false
+
+#load graphson file on startup
+load.snapshot.file=false
diff --git a/aai-traversal/bundleconfig-local/etc/auth/aai_keystore b/aai-traversal/bundleconfig-local/etc/auth/aai_keystore
new file mode 100644 (file)
index 0000000..3eef135
Binary files /dev/null and b/aai-traversal/bundleconfig-local/etc/auth/aai_keystore differ
diff --git a/aai-traversal/bundleconfig-local/etc/query/stored-queries.properties b/aai-traversal/bundleconfig-local/etc/query/stored-queries.properties
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getClfiRoadmTailSummary-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getClfiRoadmTailSummary-1.0.json
new file mode 100644 (file)
index 0000000..5c4f4fb
--- /dev/null
@@ -0,0 +1,101 @@
+{
+   "named-query-uuid" : "4f448e43-339f-4c1c-85f6-896c444e25ca",
+   "named-query-name" : "GetClfiRoadmTailSummary",
+   "named-query-version" : "1.0",
+   "description" : "Named query - Get CLFI ROADM Tail Summary",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "property-collect-list" : [ "link-name", "link-type", "operational-status", "speed-value", "speed-units" ],
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "property-collect-list" : [ "interface-name", "interface-role", "port-description", "equipment-identifier" ],
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "property-collect-list" : [ "pnf-name", "pnf-name2", "equip-model", "equip-type", "frame-id" ],
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "862b25a1-262a-4961-bdaa-cdc55d69785a"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "94043c37-4e73-439c-a790-0fdd697924cd"
+                     } ]
+                  } ]
+               }
+            }, {
+               "property-collect-list" : [ "link-name", "link-name2", "link-type", "link-role", "operational-status"],
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "property-collect-list" : [ "service-instance-id", "service-instance-name", "operational-status" ],
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "property-collect-list" : [ "service-type" ],
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "property-collect-list" : [ "global-customer-id", "subscriber-name" ],
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "c1d4305f-cdbd-4bbe-9069-a2f4978fd89e"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "2e1a602a-acd8-4f78-94ff-618b802a303b"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "fe012535-2c31-4a39-a739-612374c638a0"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "fe012535-2c31-4a39-a739-612374c638a0"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComplexByPnfName-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComplexByPnfName-1.0.json
new file mode 100644 (file)
index 0000000..fef6c91
--- /dev/null
@@ -0,0 +1,32 @@
+{
+   "named-query-uuid" : "d27ccfea-7098-42d7-a4cd-bbddb37bf205",
+   "named-query-name" : "getComplexByPnfName",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - get complex by pnfName",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "af91c2f7-35fc-43cf-a13d-443f385b2353"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "862b25a1-262a-4961-bdaa-cdc55d69785a"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComponentList-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComponentList-1.0.json
new file mode 100644 (file)
index 0000000..d3e307c
--- /dev/null
@@ -0,0 +1,98 @@
+{
+   "named-query-uuid" : "ed0a0f5b-cf79-4784-88b2-911cd726cd3d",
+   "named-query-name" : "get-component-list",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - Get Component List",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "3d560d81-57d0-438b-a2a1-5334dba0651a"
+                     } ]
+                  } ]
+               }
+            }, {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "fcec1b02-b2d0-4834-aef8-d71be04717dd"
+                           } ]
+                        } ]
+                     }
+                  }, {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "3d560d81-57d0-438b-a2a1-5334dba0651a"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "fcec1b02-b2d0-4834-aef8-d71be04717dd"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "ef86f9c5-2165-44f3-8fc3-96018b609ea5"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComponentList-1.1.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComponentList-1.1.json
new file mode 100644 (file)
index 0000000..639cd41
--- /dev/null
@@ -0,0 +1,125 @@
+{
+   "named-query-uuid" : "0367193e-c785-4d5f-9cb8-7bc89dc9ddb7",
+   "named-query-name" : "get-component-list",
+   "named-query-version" : "1.1",
+   "description" : "Named Query - Get Component List",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "property-collect-list" : [ "service-instance-id", "service-instance-name" ],
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "1b2c9ba7-e449-4831-ba15-3073672f5ef2"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "3d560d81-57d0-438b-a2a1-5334dba0651a"
+                     } ]
+                  } ]
+               }
+            }, {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "fcec1b02-b2d0-4834-aef8-d71be04717dd"
+                           } ]
+                        } ]
+                     }
+                  }, {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "fcec1b02-b2d0-4834-aef8-d71be04717dd"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "1b2c9ba7-e449-4831-ba15-3073672f5ef2"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "3d560d81-57d0-438b-a2a1-5334dba0651a"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "ef86f9c5-2165-44f3-8fc3-96018b609ea5"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComponentList-1.2.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getComponentList-1.2.json
new file mode 100644 (file)
index 0000000..22ba4c0
--- /dev/null
@@ -0,0 +1,139 @@
+{
+   "named-query-uuid" : "2a183f99-2c66-482b-ade5-7962efd801ef",
+   "named-query-name" : "get-component-list",
+   "named-query-version" : "1.2",
+   "description" : "Named Query - Get Component List",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "property-collect-list" : [ "service-instance-id", "service-instance-name" ],
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "1b2c9ba7-e449-4831-ba15-3073672f5ef2"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "3d560d81-57d0-438b-a2a1-5334dba0651a"
+                     } ]
+                  } ]
+               }
+            }, {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "fcec1b02-b2d0-4834-aef8-d71be04717dd"
+                           } ]
+                        } ]
+                     }
+                  }, {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "do-not-output" : "true",
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "6d932c8f-463b-4e76-83fb-87acfbaa2e2d"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "fcec1b02-b2d0-4834-aef8-d71be04717dd"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "1b2c9ba7-e449-4831-ba15-3073672f5ef2"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "3d560d81-57d0-438b-a2a1-5334dba0651a"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "ef86f9c5-2165-44f3-8fc3-96018b609ea5"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVComplexHostname-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVComplexHostname-1.0.json
new file mode 100644 (file)
index 0000000..a610aa6
--- /dev/null
@@ -0,0 +1,32 @@
+{
+   "named-query-uuid" : "670a94e9-874f-4087-8501-62d4d289c519",
+   "named-query-name" : "dhv-complex-by-hostname",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - DHV Complex By Hostname",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "af91c2f7-35fc-43cf-a13d-443f385b2353"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "6d932c8f-463b-4e76-83fb-87acfbaa2e2d"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVComplexLocationId-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVComplexLocationId-1.0.json
new file mode 100644 (file)
index 0000000..70d6db1
--- /dev/null
@@ -0,0 +1,32 @@
+{
+   "named-query-uuid" : "59490c32-eaae-488d-8442-f301b1ed43a9",
+   "named-query-name" : "dhv-complex-by-location-id",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - DHV Complex By LocationId",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "6d932c8f-463b-4e76-83fb-87acfbaa2e2d"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "af91c2f7-35fc-43cf-a13d-443f385b2353"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVLogicalLink-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVLogicalLink-1.0.json
new file mode 100644 (file)
index 0000000..6e90b61
--- /dev/null
@@ -0,0 +1,58 @@
+{
+   "named-query-uuid" : "47e5e7c7-719e-45af-b96f-0c15fa0691b9",
+   "named-query-name" : "logical-link-by-vnf-name",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - get logical-link by vnf-name",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "fe012535-2c31-4a39-a739-612374c638a0"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "cea0a982-8d55-4093-921e-418fbccf7060"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVLogicalLinkByCircuitId-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVLogicalLinkByCircuitId-1.0.json
new file mode 100644 (file)
index 0000000..62de1b8
--- /dev/null
@@ -0,0 +1,19 @@
+{
+   "named-query-uuid" : "4028faed-b7d5-4059-9d49-7df06da9ebfb",
+   "named-query-name" : "logical-link-by-circuit-id-",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - get logical-link by circuit-id",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "fe012535-2c31-4a39-a739-612374c638a0"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVServiceTopology-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVServiceTopology-1.0.json
new file mode 100644 (file)
index 0000000..a0ba2fe
--- /dev/null
@@ -0,0 +1,273 @@
+{
+   "named-query-uuid" : "b546a34b-7e71-45dc-9907-4cbdcf675c64",
+   "named-query-name" : "dhv-service-topology",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - DHV Service Topology",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "property-collect-list" : [ "service-instance-id", "persona-model-id", "service-instance-name", "service-instance-location-id" ],
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "property-collect-list" : [ "service-type", "temp-ub-sub-account-id" ],
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "property-collect-list" : [ "global-customer-id" ],
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "c1d4305f-cdbd-4bbe-9069-a2f4978fd89e"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "2e1a602a-acd8-4f78-94ff-618b802a303b"
+                     } ]
+                  } ]
+               }
+            }, {
+               "property-collect-list" : [ "service-instance-id", "persona-model-id", "service-instance-name", "service-instance-location-id" ],
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "property-collect-list" : [ "vnf-name", "vnf-id", "vnf-type", "prov-status", "operational-state" ],
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "property-collect-list" : [ "interface-name" ],
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "property-collect-list" : [ "vlan-interface", "vlan-id-inner", "vlan-id-outer", "vlan-description", "speed-value", "speed-units" ],
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "property-collect-list" : [ "l3-interface-ipv4-address" ],
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                             } ]
+                                          } ]
+                                       }
+                                    }, {
+                                       "property-collect-list" : [ "l3-interface-ipv6-address" ],
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8"
+                                       } ]
+                                    } ]
+                                 }
+                              }, {
+                                 "property-collect-list" : [ "l3-interface-ipv4-address" ],
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                       } ]
+                                    } ]
+                                 }
+                              }, {
+                                 "property-collect-list" : [ "l3-interface-ipv6-address" ],
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "cea0a982-8d55-4093-921e-418fbccf7060"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "property-collect-list" : [ "vserver-name", "vserver-id", "prov-status" ],
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "property-collect-list" : [ "interface-name" ],
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "property-collect-list" : [ "vlan-interface", "vlan-id-inner", "vlan-id-outer", "vlan-description", "speed-value", "speed-units" ],
+                                       "named-query-elements" : {
+                                          "named-query-element" : [ {
+                                             "property-collect-list" : [ "l3-interface-ipv4-address" ],
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                                   } ]
+                                                } ]
+                                             }
+                                          }, {
+                                             "property-collect-list" : [ "l3-interface-ipv6-address" ],
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                                   } ]
+                                                } ]
+                                             }
+                                          } ]
+                                       },
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8"
+                                             } ]
+                                          } ]
+                                       }
+                                    }, {
+                                       "property-collect-list" : [ "l3-interface-ipv4-address" ],
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                             } ]
+                                          } ]
+                                       }
+                                    }, {
+                                       "property-collect-list" : [ "l3-interface-ipv6-address" ],
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "cea0a982-8d55-4093-921e-418fbccf7060"
+                                       } ]
+                                    } ]
+                                 }
+                              }, {
+                                 "property-collect-list" : [ "hostname" ],
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "property-collect-list" : [ "interface-name" ],
+                                       "named-query-elements" : {
+                                          "named-query-element" : [ {
+                                             "property-collect-list" : [ "service-provider-name" ],
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "c822d81f-822f-4304-9623-1025b53da568"
+                                                   } ]
+                                                } ]
+                                             }
+                                          } ]
+                                       },
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "94043c37-4e73-439c-a790-0fdd697924cd"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "6d932c8f-463b-4e76-83fb-87acfbaa2e2d"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVServiceTopology-1.1.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVServiceTopology-1.1.json
new file mode 100644 (file)
index 0000000..2512590
--- /dev/null
@@ -0,0 +1,273 @@
+{
+   "named-query-uuid" : "888d6065-e1ff-409c-ac6b-baafc4777788",
+   "named-query-name" : "dhv-service-topology",
+   "named-query-version" : "1.1",
+   "description" : "Named Query - DHV Service Topology",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "property-collect-list" : [ "service-instance-id", "model-invariant-id", "service-instance-name", "service-instance-location-id" ],
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "property-collect-list" : [ "service-type", "temp-ub-sub-account-id" ],
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "property-collect-list" : [ "global-customer-id" ],
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "c1d4305f-cdbd-4bbe-9069-a2f4978fd89e"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "2e1a602a-acd8-4f78-94ff-618b802a303b"
+                     } ]
+                  } ]
+               }
+            }, {
+               "property-collect-list" : [ "service-instance-id", "persona-model-id", "service-instance-name", "service-instance-location-id" ],
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "property-collect-list" : [ "vnf-name", "vnf-id", "vnf-type", "prov-status", "operational-state" ],
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "property-collect-list" : [ "interface-name" ],
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "property-collect-list" : [ "vlan-interface", "vlan-id-inner", "vlan-id-outer", "vlan-description", "speed-value", "speed-units" ],
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "property-collect-list" : [ "l3-interface-ipv4-address" ],
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                             } ]
+                                          } ]
+                                       }
+                                    }, {
+                                       "property-collect-list" : [ "l3-interface-ipv6-address" ],
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8"
+                                       } ]
+                                    } ]
+                                 }
+                              }, {
+                                 "property-collect-list" : [ "l3-interface-ipv4-address" ],
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                       } ]
+                                    } ]
+                                 }
+                              }, {
+                                 "property-collect-list" : [ "l3-interface-ipv6-address" ],
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "cea0a982-8d55-4093-921e-418fbccf7060"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "property-collect-list" : [ "vserver-name", "vserver-id", "prov-status" ],
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "property-collect-list" : [ "interface-name" ],
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "property-collect-list" : [ "vlan-interface", "vlan-id-inner", "vlan-id-outer", "vlan-description", "speed-value", "speed-units" ],
+                                       "named-query-elements" : {
+                                          "named-query-element" : [ {
+                                             "property-collect-list" : [ "l3-interface-ipv4-address" ],
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                                   } ]
+                                                } ]
+                                             }
+                                          }, {
+                                             "property-collect-list" : [ "l3-interface-ipv6-address" ],
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                                   } ]
+                                                } ]
+                                             }
+                                          } ]
+                                       },
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8"
+                                             } ]
+                                          } ]
+                                       }
+                                    }, {
+                                       "property-collect-list" : [ "l3-interface-ipv4-address" ],
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                             } ]
+                                          } ]
+                                       }
+                                    }, {
+                                       "property-collect-list" : [ "l3-interface-ipv6-address" ],
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "cea0a982-8d55-4093-921e-418fbccf7060"
+                                       } ]
+                                    } ]
+                                 }
+                              }, {
+                                 "property-collect-list" : [ "hostname" ],
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "property-collect-list" : [ "interface-name" ],
+                                       "named-query-elements" : {
+                                          "named-query-element" : [ {
+                                             "property-collect-list" : [ "service-provider-name" ],
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "c822d81f-822f-4304-9623-1025b53da568"
+                                                   } ]
+                                                } ]
+                                             }
+                                          } ]
+                                       },
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "94043c37-4e73-439c-a790-0fdd697924cd"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "6d932c8f-463b-4e76-83fb-87acfbaa2e2d"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVServiceTopology2-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getDHVServiceTopology2-1.0.json
new file mode 100644 (file)
index 0000000..986c50a
--- /dev/null
@@ -0,0 +1,321 @@
+{
+   "named-query-uuid" : "09236f18-a9d2-4468-9086-464b8385b706",
+   "named-query-name" : "dhv-service-topology-2",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - DHV Service Topology 2",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                       } ]
+                                    } ]
+                                 }
+                              }, {
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "cea0a982-8d55-4093-921e-418fbccf7060"
+                           } ]
+                        } ]
+                     }
+                  }, {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "af91c2f7-35fc-43cf-a13d-443f385b2353"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "6d932c8f-463b-4e76-83fb-87acfbaa2e2d"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                     } ]
+                  } ]
+               }
+            }, {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                             } ]
+                                          } ]
+                                       }
+                                    }, {
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                             } ]
+                                          } ]
+                                       }
+                                    }, {
+                                       "named-query-elements" : {
+                                          "named-query-element" : [ {
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                                   } ]
+                                                } ]
+                                             }
+                                          }, {
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                                   } ]
+                                                } ]
+                                             }
+                                          } ]
+                                       },
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "cea0a982-8d55-4093-921e-418fbccf7060"
+                                       } ]
+                                    } ]
+                                 }
+                              }, {
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "named-query-elements" : {
+                                          "named-query-element" : [ {
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                                   } ]
+                                                } ]
+                                             }
+                                          }, {
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                                   } ]
+                                                } ]
+                                             }
+                                          }, {
+                                             "named-query-elements" : {
+                                                "named-query-element" : [ {
+                                                   "relationship-list" : {
+                                                      "relationship" : [ {
+                                                         "related-to" : "model",
+                                                         "relationship-data" : [ {
+                                                            "relationship-key" : "model.model-invariant-id",
+                                                            "relationship-value" : "aad85df2-09be-40fa-b867-16415e4e10e2"
+                                                         } ]
+                                                      } ]
+                                                   }
+                                                }, {
+                                                   "relationship-list" : {
+                                                      "relationship" : [ {
+                                                         "related-to" : "model",
+                                                         "relationship-data" : [ {
+                                                            "relationship-key" : "model.model-invariant-id",
+                                                            "relationship-value" : "82966045-43ee-4982-8307-7e9610866140"
+                                                         } ]
+                                                      } ]
+                                                   }
+                                                } ]
+                                             },
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8"
+                                                   } ]
+                                                } ]
+                                             }
+                                          } ]
+                                       },
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "cea0a982-8d55-4093-921e-418fbccf7060"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "f6d6a23d-a1a9-48ff-8419-b6530da2d381"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getL3networkCloudRegionByNetworkRole-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getL3networkCloudRegionByNetworkRole-1.0.json
new file mode 100644 (file)
index 0000000..d6b3c34
--- /dev/null
@@ -0,0 +1,71 @@
+{
+   "named-query-uuid" : "96e54642-c0e1-4aa2-af53-e37c623b8d01",
+   "named-query-name" : "l3network-cloud-region-by-network-role",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - get l3Network and cloudRegion by networkRole",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "425b2158-e51d-4509-9945-dad4556474a3"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "97c26c99-6870-44c1-8a07-1d900d3f4ce6"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "3d560d81-57d0-438b-a2a1-5334dba0651a"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getLogicalLinkByCloudRegionId-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getLogicalLinkByCloudRegionId-1.0.json
new file mode 100644 (file)
index 0000000..e987d36
--- /dev/null
@@ -0,0 +1,32 @@
+{
+   "named-query-uuid" : "25096aa7-bc97-4ece-8a81-41dd28cd0f7d",
+   "named-query-name" : "getLogicalLinkByCloudRegionId",
+   "named-query-version" : "1.0",
+   "description" : "Named query - get logical link by cloud region id",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "fe012535-2c31-4a39-a739-612374c638a0"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "425b2158-e51d-4509-9945-dad4556474a3"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getPinterfacePhysicalLinkBySvcInstId-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getPinterfacePhysicalLinkBySvcInstId-1.0.json
new file mode 100644 (file)
index 0000000..e8b377b
--- /dev/null
@@ -0,0 +1,84 @@
+{
+   "named-query-uuid" : "75d55786-200b-49fd-92d7-1393e755d693",
+   "named-query-name" : "pinterface-physical-link-by-service-instance-id",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - get pInterface and physicalLink by serviceInstanceId",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "c822d81f-822f-4304-9623-1025b53da568"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "94043c37-4e73-439c-a790-0fdd697924cd"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "6d932c8f-463b-4e76-83fb-87acfbaa2e2d"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getRouterRoadmTailSummary-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getRouterRoadmTailSummary-1.0.json
new file mode 100644 (file)
index 0000000..0fb6dd5
--- /dev/null
@@ -0,0 +1,129 @@
+{
+   "named-query-uuid" : "cbf22b8a-f29a-4b9b-a466-a878095b258a",
+   "named-query-name" : "GetRouterRoadmTailSummary",
+   "named-query-version" : "1.0",
+   "description" : "Named query - Get Router ROADM Tail Summary",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "property-collect-list" : [ "pnf-name", "pnf-name2", "equip-model", "equip-type", "frame-id" ],
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "property-collect-list" : [ "interface-name", "port-description", "equipment-identifier" ],
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "property-collect-list" : [ "link-name", "link-type", "operational-status", "speed-value", "speed-units" ],
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "property-collect-list" : [ "interface-name", "interface-role", "port-description", "equipment-identifier" ],
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "property-collect-list" : [ "pnf-name", "equip-model", "equip-type", "frame-id" ],
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "862b25a1-262a-4961-bdaa-cdc55d69785a"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "94043c37-4e73-439c-a790-0fdd697924cd"
+                                 } ]
+                              } ]
+                           }
+                        }, {
+                           "property-collect-list" : [ "link-name", "link-name2", "link-type", "link-role", "operational-status" ],
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "property-collect-list" : [ "service-instance-id", "service-instance-name", "operational-status" ],
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "property-collect-list" : [ "service-type" ],
+                                       "named-query-elements" : {
+                                          "named-query-element" : [ {
+                                             "property-collect-list" : [ "global-customer-id", "subscriber-name" ],
+                                             "relationship-list" : {
+                                                "relationship" : [ {
+                                                   "related-to" : "model",
+                                                   "relationship-data" : [ {
+                                                      "relationship-key" : "model.model-invariant-id",
+                                                      "relationship-value" : "c1d4305f-cdbd-4bbe-9069-a2f4978fd89e"
+                                                   } ]
+                                                } ]
+                                             }
+                                          } ]
+                                       },
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "2e1a602a-acd8-4f78-94ff-618b802a303b"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "fe012535-2c31-4a39-a739-612374c638a0"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "fe012535-2c31-4a39-a739-612374c638a0"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "94043c37-4e73-439c-a790-0fdd697924cd"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "862b25a1-262a-4961-bdaa-cdc55d69785a"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getServiceInstanceSummary-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getServiceInstanceSummary-1.0.json
new file mode 100644 (file)
index 0000000..971b1a2
--- /dev/null
@@ -0,0 +1,126 @@
+{
+   "named-query-uuid" : "5aaae840-ca96-4e5f-9308-58883564a80f",
+   "named-query-name" : "get-service-instance-summary",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - Get Service Instance Summary",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "property-collect-list" : [ "service-instance-id", "service-instance-name", "operational-status" ],
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "do-not-output" : "true",
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "property-collect-list" : [ "cloud-region-id" ],
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "425b2158-e51d-4509-9945-dad4556474a3"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "3d560d81-57d0-438b-a2a1-5334dba0651a"
+                     } ]
+                  } ]
+               }
+            }, {
+               "property-collect-list" : [ "service-type" ],
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "property-collect-list" : [ "global-customer-id", "subscriber-name" ],
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "c1d4305f-cdbd-4bbe-9069-a2f4978fd89e"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "2e1a602a-acd8-4f78-94ff-618b802a303b"
+                     } ]
+                  } ]
+               }
+            }, {
+               "do-not-output" : "true",
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "do-not-output" : "true",
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "do-not-output" : "true",
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "property-collect-list" : [ "cloud-region-id" ],
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "425b2158-e51d-4509-9945-dad4556474a3"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "97c26c99-6870-44c1-8a07-1d900d3f4ce6"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getSvcSubscriberModelInfo-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getSvcSubscriberModelInfo-1.0.json
new file mode 100644 (file)
index 0000000..5dcd475
--- /dev/null
@@ -0,0 +1,46 @@
+{
+   "named-query-uuid" : "6e806bc2-8f9b-4534-bb68-be91267ff6c8",
+   "named-query-name" : "get-service-instance-model-info",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - Get Service Instance Model Info",
+    "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "do-not-output" : "false",
+               "related-lookups" : {
+                  "related-lookup" : [ {
+                     "source-node-type" : "service-instance",
+                     "source-node-property" : "model-invariant-id-local",
+                     "target-node-type" : "model",
+                     "target-node-property" : "model-invariant-id",
+                     "property-collect-list" : ["model-invariant-id", "model-type", "model-description" ]
+                  }, {
+                     "source-node-type" : "service-instance",
+                     "source-node-property" : "model-version-id-local",
+                     "target-node-type" : "model-ver",
+                     "target-node-property" : "model-version-id",
+                     "property-collect-list" : [ "model-version-id", "model-name", "model-version", "model-description" ]
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "2e1a602a-acd8-4f78-94ff-618b802a303b"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getTenantInfoAtSvcInstance-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getTenantInfoAtSvcInstance-1.0.json
new file mode 100644 (file)
index 0000000..ee1bec5
--- /dev/null
@@ -0,0 +1,87 @@
+{
+   "named-query-uuid" : "3c167fdb-5a99-46a3-8165-e566d289358d",
+   "named-query-name" : "getTenantInfoAtSvcInstance",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - Tenant Info At Service Instance",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "property-collect-list" : [ "service-instance-id", "service-instance-name" ],
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "property-collect-list" : [ "vnf-id", "vnf-name" ],
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "property-collect-list" : [ "vserver-id", "vserver-name" ],
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "named-query-elements" : {
+                                    "named-query-element" : [ {
+                                       "relationship-list" : {
+                                          "relationship" : [ {
+                                             "related-to" : "model",
+                                             "relationship-data" : [ {
+                                                "relationship-key" : "model.model-invariant-id",
+                                                "relationship-value" : "af91c2f7-35fc-43cf-a13d-443f385b2353"
+                                             } ]
+                                          } ]
+                                       }
+                                    } ]
+                                 },
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "425b2158-e51d-4509-9945-dad4556474a3"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "97c26c99-6870-44c1-8a07-1d900d3f4ce6"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getTenantInfoAtSvcSubscription-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getTenantInfoAtSvcSubscription-1.0.json
new file mode 100644 (file)
index 0000000..e520585
--- /dev/null
@@ -0,0 +1,58 @@
+{
+   "named-query-uuid" : "35b13965-ef9d-4597-9859-bde64c521c91",
+   "named-query-name" : "getTenantInfoAtSvcSubscription",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - Tenant Info At ServiceSubscription",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "af91c2f7-35fc-43cf-a13d-443f385b2353"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "425b2158-e51d-4509-9945-dad4556474a3"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "97c26c99-6870-44c1-8a07-1d900d3f4ce6"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "2e1a602a-acd8-4f78-94ff-618b802a303b"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getVnfVlanByCircuitId-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getVnfVlanByCircuitId-1.0.json
new file mode 100644 (file)
index 0000000..2260ab3
--- /dev/null
@@ -0,0 +1,58 @@
+{
+   "named-query-uuid" : "9abb2661-d92c-4f84-aea6-b16acfa00e22",
+   "named-query-name" : "generic-vnf-vlan-by-circuit-id",
+   "named-query-version" : "1.0",
+   "description" : "Named Query - get genericVnf and vlan by circuitId",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "acc6edd8-a8d4-4b93-afaa-0994068be14c"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "cea0a982-8d55-4093-921e-418fbccf7060"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "fe012535-2c31-4a39-a739-612374c638a0"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getWlBundleId-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/named-query-json/getWlBundleId-1.0.json
new file mode 100644 (file)
index 0000000..203aa38
--- /dev/null
@@ -0,0 +1,81 @@
+{
+   "named-query-uuid" : "88aae9bc-9b3d-44c8-a0ba-3c4911da755c",
+   "named-query-name" : "GetWlBundleId",
+   "named-query-version" : "1.0",
+   "description" : "Named query for wavelength services with same Bundle Id",
+   "named-query-elements" : {
+      "named-query-element" : [ {
+         "named-query-elements" : {
+            "named-query-element" : [ {
+               "named-query-elements" : {
+                  "named-query-element" : [ {
+                     "named-query-elements" : {
+                        "named-query-element" : [ {
+                           "named-query-elements" : {
+                              "named-query-element" : [ {
+                                 "relationship-list" : {
+                                    "relationship" : [ {
+                                       "related-to" : "model",
+                                       "relationship-data" : [ {
+                                          "relationship-key" : "model.model-invariant-id",
+                                          "relationship-value" : "c1d4305f-cdbd-4bbe-9069-a2f4978fd89e"
+                                       } ]
+                                    } ]
+                                 }
+                              } ]
+                           },
+                           "relationship-list" : {
+                              "relationship" : [ {
+                                 "related-to" : "model",
+                                 "relationship-data" : [ {
+                                    "relationship-key" : "model.model-invariant-id",
+                                    "relationship-value" : "2e1a602a-acd8-4f78-94ff-618b802a303b"
+                                 } ]
+                              } ]
+                           }
+                        } ]
+                     },
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "82194af1-3c2c-485a-8f44-420e22a9eaa4"
+                           } ]
+                        } ]
+                     }
+                  }, {
+                     "relationship-list" : {
+                        "relationship" : [ {
+                           "related-to" : "model",
+                           "relationship-data" : [ {
+                              "relationship-key" : "model.model-invariant-id",
+                              "relationship-value" : "fe012535-2c31-4a39-a739-612374c638a0"
+                           } ]
+                        } ]
+                     }
+                  } ]
+               },
+               "relationship-list" : {
+                  "relationship" : [ {
+                     "related-to" : "model",
+                     "relationship-data" : [ {
+                        "relationship-key" : "model.model-invariant-id",
+                        "relationship-value" : "fe012535-2c31-4a39-a739-612374c638a0"
+                     } ]
+                  } ]
+               }
+            } ]
+         },
+         "relationship-list" : {
+            "relationship" : [ {
+               "related-to" : "model",
+               "relationship-data" : [ {
+                  "relationship-key" : "model.model-invariant-id",
+                  "relationship-value" : "86ffe6e5-4d0e-4cec-80b5-5c38aa3eff98"
+               } ]
+            } ]
+         }
+      } ]
+   }
+}
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/resource-model-json/000-README b/aai-traversal/bundleconfig-local/etc/scriptdata/resource-model-json/000-README
new file mode 100644 (file)
index 0000000..9647972
--- /dev/null
@@ -0,0 +1,10 @@
+Add resource models here in the order you want them to be added to the graph.
+
+Recommended that they are spaced by 10's.
+
+So, if you are adding a resource model it should be:
+
+100-ipe-resource-model-1.0.json
+110-vBgf-resource-model-1.0.json
+
+This will allow others to insert models between existing models.
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/service-model-json/000-README b/aai-traversal/bundleconfig-local/etc/scriptdata/service-model-json/000-README
new file mode 100644 (file)
index 0000000..bb30e02
--- /dev/null
@@ -0,0 +1,10 @@
+Add service models here in the order you want them to be added to the graph.
+
+Recommended that they are spaced by 10's.
+
+So, if you are adding a resource model it should be:
+
+100-connector-service-model-1.0.json
+110-service-instance-service-model-1.0.json
+
+This will allow others to insert models between existing models.
\ No newline at end of file
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/action-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/action-1.0.json
new file mode 100644 (file)
index 0000000..9d3e00c
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "af593b4b-490e-4665-ad74-2f6351c0a7ce",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "fd7fb09e-d930-41b9-b83f-cfde9df48640",
+                       "model-version" : "1.0",
+                       "model-name" : "action"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/action-data-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/action-data-1.0.json
new file mode 100644 (file)
index 0000000..7229f5a
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "9551346c-7d8b-4daf-9926-b93e96e2344a",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd",
+                       "model-version" : "1.0",
+                       "model-name" : "action-data"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/allotted-resource-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/allotted-resource-1.0.json
new file mode 100644 (file)
index 0000000..9329af8
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "f6d6a23d-a1a9-48ff-8419-b6530da2d381",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "7ad0915f-25c0-4a70-b9bc-185a75f87564",
+                       "model-version" : "1.0",
+                       "model-name" : "allotted-resource"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/availability-zone-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/availability-zone-1.0.json
new file mode 100644 (file)
index 0000000..0c423fe
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "61b88c01-d819-41c0-8e21-7fd7ba47148e",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "6c092fb1-21b2-456b-9e01-67fb4de1896e",
+                       "model-version" : "1.0",
+                       "model-name" : "availability-zone"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/az-and-dvs-switches-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/az-and-dvs-switches-1.0.json
new file mode 100644 (file)
index 0000000..620a33d
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "53dc00d4-e6d9-48ec-b6cc-3d3797e9b896",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "b2dea88d-78a0-49bf-95c9-5819df08e966",
+                       "model-version" : "1.0",
+                       "model-name" : "az-and-dvs-switches"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/class-of-service-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/class-of-service-1.0.json
new file mode 100644 (file)
index 0000000..2b28152
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "18094b19-d16d-4822-8acf-e92c6aefa178",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "d2fb27cc-15eb-4c4e-828e-71d41aaecc5b",
+                       "model-version" : "1.0",
+                       "model-name" : "class-of-service"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/cloud-region-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/cloud-region-1.0.json
new file mode 100644 (file)
index 0000000..a2957c4
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "425b2158-e51d-4509-9945-dad4556474a3",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "2a160989-b202-47dd-874b-4a0f275998f7",
+                       "model-version" : "1.0",
+                       "model-name" : "cloud-region"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/complex-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/complex-1.0.json
new file mode 100644 (file)
index 0000000..c8ca766
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "af91c2f7-35fc-43cf-a13d-443f385b2353",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "3a8ab1ee-9220-4fe8-b89c-9251d160ddc2",
+                       "model-version" : "1.0",
+                       "model-name" : "complex"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/connector-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/connector-1.0.json
new file mode 100644 (file)
index 0000000..f9bfed0
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "4c01c948-7607-4d66-8a6c-99c2c2717936",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "22104c9f-29fd-462f-be07-96cd6b46dd33",
+                       "model-version" : "1.0",
+                       "model-name" : "connector"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/constrained-element-set-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/constrained-element-set-1.0.json
new file mode 100644 (file)
index 0000000..44f5de2
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "c0292b4f-ee97-40cc-8c2e-f967c48f5701",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "01102126-9c04-4a89-945b-b131e61e95d7",
+                       "model-version" : "1.0",
+                       "model-name" : "constrained-element-set"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/ctag-assignment-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/ctag-assignment-1.0.json
new file mode 100644 (file)
index 0000000..87eee5c
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "fcb8d46b-b656-4ad6-8fa4-22cef74b443f",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "44e5cb1f-0938-41aa-b766-d4595109fe89",
+                       "model-version" : "1.0",
+                       "model-name" : "ctag-assignment"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/ctag-pool-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/ctag-pool-1.0.json
new file mode 100644 (file)
index 0000000..c85e267
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "46c51d4e-d67e-4a9c-b1f5-49b1e9c6fcaa",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "2056c41f-23b9-4de7-9f50-819adad37d76",
+                       "model-version" : "1.0",
+                       "model-name" : "ctag-pool"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/customer-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/customer-1.0.json
new file mode 100644 (file)
index 0000000..35cf683
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "c1d4305f-cdbd-4bbe-9069-a2f4978fd89e",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "d4df5c27-98a1-4812-a8aa-c17f055b7a3f",
+                       "model-version" : "1.0",
+                       "model-name" : "customer"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/cvlan-tag-entry-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/cvlan-tag-entry-1.0.json
new file mode 100644 (file)
index 0000000..95211f2
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "245cf4b0-7cc5-4eea-bbd9-753e939adcab",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "c3878ffb-8d85-4114-bee6-e4074a9db10b",
+                       "model-version" : "1.0",
+                       "model-name" : "cvlan-tag-entry"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/dvs-switch-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/dvs-switch-1.0.json
new file mode 100644 (file)
index 0000000..22dc769
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "98fbb471-1f86-428e-bd8a-c8a25de6fa23",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "4cb44ae8-e3ab-452a-9f95-bcc8a44c55ea",
+                       "model-version" : "1.0",
+                       "model-name" : "dvs-switch"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/edge-prop-names-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/edge-prop-names-1.0.json
new file mode 100644 (file)
index 0000000..4ed663f
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "7a08cad4-8759-46a5-8245-095d1ba57ac6",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "f0442326-8201-4d0e-857c-74b4ddcbfc9f",
+                       "model-version" : "1.0",
+                       "model-name" : "edge-prop-names"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/element-choice-set-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/element-choice-set-1.0.json
new file mode 100644 (file)
index 0000000..46c7348
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "9a011958-7165-47a3-b872-00951d1f09ae",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "af27fbfd-598d-44da-aeae-0f9d3a5fcd6a",
+                       "model-version" : "1.0",
+                       "model-name" : "element-choice-set"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/entitlement-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/entitlement-1.0.json
new file mode 100644 (file)
index 0000000..b6bf0e8
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "ae75b5a0-d5e1-4f3a-b8fb-37626a753da3",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "7e27ba2e-b7db-4e13-9fae-d142152ef98a",
+                       "model-version" : "1.0",
+                       "model-name" : "entitlement"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/flavor-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/flavor-1.0.json
new file mode 100644 (file)
index 0000000..c44e554
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "bace8d1c-a261-4041-9e37-823117415d0f",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "36200fb5-f251-4f5d-a520-7c5ad5c2cd4b",
+                       "model-version" : "1.0",
+                       "model-name" : "flavor"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/generic-vnf-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/generic-vnf-1.0.json
new file mode 100644 (file)
index 0000000..afab83a
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "acc6edd8-a8d4-4b93-afaa-0994068be14c",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "93a6166f-b3d5-4f06-b4ba-aed48d009ad9",
+                       "model-version" : "1.0",
+                       "model-name" : "generic-vnf"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/group-assignment-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/group-assignment-1.0.json
new file mode 100644 (file)
index 0000000..33e1495
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "7cc05f25-7ba2-42b7-a237-c5662a1689e1",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "fe578080-ce19-4604-8760-fc264fbb2565",
+                       "model-version" : "1.0",
+                       "model-name" : "group-assignment"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/image-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/image-1.0.json
new file mode 100644 (file)
index 0000000..59f095b
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "3f4c7204-739b-4bbb-87a7-8a6856439c90",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "f6a038c2-820c-42ba-8c2b-375e24e8f932",
+                       "model-version" : "1.0",
+                       "model-name" : "image"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/include-node-filter-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/include-node-filter-1.0.json
new file mode 100644 (file)
index 0000000..83d9255
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "2a2d8ad2-af0a-4e1f-9982-0c899e7dc827",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "f05f804d-7057-4ffe-bdc5-39f2f0c9c9fd",
+                       "model-version" : "1.0",
+                       "model-name" : "include-node-filter"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/instance-group-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/instance-group-1.0.json
new file mode 100644 (file)
index 0000000..81eeff0
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "3bf1e610-45f7-4ad6-b833-ca4c5ee6a3fd",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "8e6ee9dc-9017-444a-83b3-219edb018128",
+                       "model-version" : "1.0",
+                       "model-name" : "instance-group"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/inventory-item-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/inventory-item-1.0.json
new file mode 100644 (file)
index 0000000..307d29d
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "cd57d844-9017-4078-aa19-926935a3d77c",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "69957f4a-2155-4b95-8d72-d6dd9b88b27b",
+                       "model-version" : "1.0",
+                       "model-name" : "inventory-item"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/inventory-item-data-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/inventory-item-data-1.0.json
new file mode 100644 (file)
index 0000000..46cb9f0
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "87a383ae-cf03-432e-a9de-04e6a622d0fd",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "0e54bb87-bd6e-4a2b-ad1c-6d935b87ae51",
+                       "model-version" : "1.0",
+                       "model-name" : "inventory-item-data"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/ipsec-configuration-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/ipsec-configuration-1.0.json
new file mode 100644 (file)
index 0000000..165ebbe
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "aca4c310-cb45-42bd-9f88-73e40ba7b962",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "d949fd10-36bf-408a-ac7a-cad5004d2e0d",
+                       "model-version" : "1.0",
+                       "model-name" : "ipsec-configuration"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/key-data-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/key-data-1.0.json
new file mode 100644 (file)
index 0000000..f0f7cb4
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "f5faa464-c2f2-4cc3-89d2-a90452dc3a07",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "c23ea04d-1a3b-453d-bc49-a6c783a5e92b",
+                       "model-version" : "1.0",
+                       "model-name" : "key-data"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l-interface-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l-interface-1.0.json
new file mode 100644 (file)
index 0000000..0f63ba5
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "cea0a982-8d55-4093-921e-418fbccf7060",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "a32613fd-18b9-459e-aab8-fffb3912966a",
+                       "model-version" : "1.0",
+                       "model-name" : "l-interface"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l3-interface-ipv4-address-list-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l3-interface-ipv4-address-list-1.0.json
new file mode 100644 (file)
index 0000000..0bb4d41
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "aad85df2-09be-40fa-b867-16415e4e10e2",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "41e76b6f-1e06-4fd4-82cd-81c50fc4574b",
+                       "model-version" : "1.0",
+                       "model-name" : "l3-interface-ipv4-address-list"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l3-interface-ipv6-address-list-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l3-interface-ipv6-address-list-1.0.json
new file mode 100644 (file)
index 0000000..9a830f4
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "82966045-43ee-4982-8307-7e9610866140",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "d040621d-541a-477b-bb1b-a2b61b14e295",
+                       "model-version" : "1.0",
+                       "model-name" : "l3-interface-ipv6-address-list"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l3-network-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/l3-network-1.0.json
new file mode 100644 (file)
index 0000000..0d92d38
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "3d560d81-57d0-438b-a2a1-5334dba0651a",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "9111f20f-e680-4001-b83f-19a2fc23bfc1",
+                       "model-version" : "1.0",
+                       "model-name" : "l3-network"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/lag-interface-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/lag-interface-1.0.json
new file mode 100644 (file)
index 0000000..9bf0715
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "e0ee9bde-c1fc-4651-a95d-8e0597bf7d70",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "ce95f7c3-b61b-4758-ae9e-7e943b1c103d",
+                       "model-version" : "1.0",
+                       "model-name" : "lag-interface"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/lag-link-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/lag-link-1.0.json
new file mode 100644 (file)
index 0000000..44046a9
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "86ffe6e5-4d0e-4cec-80b5-5c38aa3eff98",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "d29a087a-af59-4053-a3f8-0f95a92faa75",
+                       "model-version" : "1.0",
+                       "model-name" : "lag-link"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/license-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/license-1.0.json
new file mode 100644 (file)
index 0000000..fc79b60
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "b9a9b337-1f86-42d3-b9f9-f987a089507c",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "6889274b-a1dc-40ab-9090-93677e13e2e6",
+                       "model-version" : "1.0",
+                       "model-name" : "license"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/license-key-resource-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/license-key-resource-1.0.json
new file mode 100644 (file)
index 0000000..b56df16
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "9022ebfe-b54f-4911-a6b2-8c3f5ec189b7",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "24b25f8c-b8bd-4c62-9421-87c12667aac9",
+                       "model-version" : "1.0",
+                       "model-name" : "license-key-resource"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/logical-link-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/logical-link-1.0.json
new file mode 100644 (file)
index 0000000..66300e7
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "fe012535-2c31-4a39-a739-612374c638a0",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "a1481a38-f8ba-4ae4-bdf1-06c2c6af4c54",
+                       "model-version" : "1.0",
+                       "model-name" : "logical-link"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/metadatum-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/metadatum-1.0.json
new file mode 100644 (file)
index 0000000..1110746
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "86dbb63a-265e-4614-993f-6771c30b56a5",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "6bae950e-8939-41d3-a6a7-251b03e4c1fc",
+                       "model-version" : "1.0",
+                       "model-name" : "metadatum"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-1.0.json
new file mode 100644 (file)
index 0000000..4c5da8c
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "06d1418a-5faa-452d-a94b-a2829df5f67b",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "1f51c05c-b164-4c27-9c03-5cbb239fd6be",
+                       "model-version" : "1.0",
+                       "model-name" : "model"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-constraint-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-constraint-1.0.json
new file mode 100644 (file)
index 0000000..37b7272
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "c28966f3-e758-4483-b37b-a90b05d3dd33",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "ad70dd19-f156-4fb5-a865-97b5563b0d37",
+                       "model-version" : "1.0",
+                       "model-name" : "model-constraint"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-element-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-element-1.0.json
new file mode 100644 (file)
index 0000000..6e4df08
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "2076e726-3577-477a-a300-7fa65cd4df11",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "753e813a-ba9e-4a1d-ab34-b2f6dc6eec0c",
+                       "model-version" : "1.0",
+                       "model-name" : "model-element"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-ver-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/model-ver-1.0.json
new file mode 100644 (file)
index 0000000..98511b0
--- /dev/null
@@ -0,0 +1,11 @@
+{
+   "model-invariant-id" : "b5cd462f-e426-4146-b1fe-5475ae272c3d",
+   "model-type" : "widget",
+   "model-vers" : {
+      "model-ver" : [ {
+         "model-version-id" : "93f2f8bc-cb12-4a01-96c8-3d2649e4ab8f",
+         "model-name" : "model-ver",
+         "model-version" : "1.0"
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/multicast-configuration-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/multicast-configuration-1.0.json
new file mode 100644 (file)
index 0000000..c76e423
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "ea78c9e3-514d-4a0a-9162-13837fa54c35",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "666a06ee-4b57-46df-bacf-908da8f10c3f",
+                       "model-version" : "1.0",
+                       "model-name" : "multicast-configuration"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/named-query-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/named-query-1.0.json
new file mode 100644 (file)
index 0000000..7aef873
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "80b712fd-0ad3-4180-a99c-8c995cf1cc32",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "5c3b7c33-afa3-4be5-8da7-1a5ac6f99896",
+                       "model-version" : "1.0",
+                       "model-name" : "named-query"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/named-query-element-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/named-query-element-1.0.json
new file mode 100644 (file)
index 0000000..6f6d11a
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "3c504d40-b847-424c-9d25-4fb7e0a3e994",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "204c641a-3494-48c8-979a-86856f5fd32a",
+                       "model-version" : "1.0",
+                       "model-name" : "named-query-element"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/network-policy-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/network-policy-1.0.json
new file mode 100644 (file)
index 0000000..a28b19e
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "6aa05779-94d7-4d8b-9bee-59ef2ab0c246",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "a0ccd9dc-7062-4940-9bcc-e91dd28af510",
+                       "model-version" : "1.0",
+                       "model-name" : "network-policy"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/network-profile-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/network-profile-1.0.json
new file mode 100644 (file)
index 0000000..30d6d9d
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "2734b44a-b8a2-40f6-957d-6256589e5d00",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "01f45471-4240-498c-a9e1-235dc0b8b4a6",
+                       "model-version" : "1.0",
+                       "model-name" : "network-profile"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/newvce-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/newvce-1.0.json
new file mode 100644 (file)
index 0000000..b2285d4
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "4b05ec9c-c55d-4987-83ff-e08d6ddb694f",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "7c79e11f-a408-4593-aa86-ba948a1236af",
+                       "model-version" : "1.0",
+                       "model-name" : "newvce"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/oam-network-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/oam-network-1.0.json
new file mode 100644 (file)
index 0000000..7a3cd18
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "2851cf01-9c40-4064-87d4-6184a6fcff35",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "f4fb34f3-fd6e-4a8f-a3fb-4ab61a343b79",
+                       "model-version" : "1.0",
+                       "model-name" : "oam-network"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/p-interface-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/p-interface-1.0.json
new file mode 100644 (file)
index 0000000..3d02918
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "94043c37-4e73-439c-a790-0fdd697924cd",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "d2cdb2d0-fc1f-4a57-a89e-591b1c4e3754",
+                       "model-version" : "1.0",
+                       "model-name" : "p-interface"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/physical-link-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/physical-link-1.0.json
new file mode 100644 (file)
index 0000000..904a4cc
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "c822d81f-822f-4304-9623-1025b53da568",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "9c523936-95b4-4d7f-9f53-6bdfe0cf2c05",
+                       "model-version" : "1.0",
+                       "model-name" : "physical-link"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/pnf-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/pnf-1.0.json
new file mode 100644 (file)
index 0000000..9260b17
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "862b25a1-262a-4961-bdaa-cdc55d69785a",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "e9f1fa7d-c839-418a-9601-03dc0d2ad687",
+                       "model-version" : "1.0",
+                       "model-name" : "pnf"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/port-group-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/port-group-1.0.json
new file mode 100644 (file)
index 0000000..8aac84d
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "8ce940fb-55d7-4230-9e7f-a56cc2741f77",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "03e8bb6b-b48a-46ae-b5d4-e5af577e6844",
+                       "model-version" : "1.0",
+                       "model-name" : "port-group"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/property-constraint-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/property-constraint-1.0.json
new file mode 100644 (file)
index 0000000..4db5389
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "f4a863c3-6886-470a-a6ae-05723837ea45",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "81706bbd-981e-4362-ae20-995cbcb2d995",
+                       "model-version" : "1.0",
+                       "model-name" : "property-constraint"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/pserver-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/pserver-1.0.json
new file mode 100644 (file)
index 0000000..a22b859
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "6d932c8f-463b-4e76-83fb-87acfbaa2e2d",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "72f0d495-bc27-4653-9e1a-eef76bd34bc9",
+                       "model-version" : "1.0",
+                       "model-name" : "pserver"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/related-lookup-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/related-lookup-1.0.json
new file mode 100644 (file)
index 0000000..e67fa07
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "468f6f5b-2996-41bb-b2a3-7cf9613ebb9b",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "0988bab5-bf4f-4938-a419-ab249867d12a",
+                       "model-version" : "1.0",
+                       "model-name" : "related-lookup"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/reserved-prop-names-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/reserved-prop-names-1.0.json
new file mode 100644 (file)
index 0000000..1bfc7d3
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "0c3e0ba3-618c-498d-9127-c8d42b00170f",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "ac49d26d-9163-430e-934a-13b738a04f5c",
+                       "model-version" : "1.0",
+                       "model-name" : "reserved-prop-names"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/result-data-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/result-data-1.0.json
new file mode 100644 (file)
index 0000000..059dfb0
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "ff656f23-6185-406f-9006-4b26834f3e1c",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "4e9b50aa-5227-4f6f-b489-62e6bbc03c79",
+                       "model-version" : "1.0",
+                       "model-name" : "result-data"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/route-table-reference-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/route-table-reference-1.0.json
new file mode 100644 (file)
index 0000000..f7910a9
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "a8614b63-2636-4c4f-98df-fd448c4241db",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "fed7e326-03a7-45ff-a3f2-471470d268c4",
+                       "model-version" : "1.0",
+                       "model-name" : "route-table-reference"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/routing-instance-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/routing-instance-1.0.json
new file mode 100644 (file)
index 0000000..caec0d6
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "1c2ded4f-8b01-4193-829c-966847dfec3e",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "3ccbcbc7-d19e-44d5-a52f-7e18aa8d69fa",
+                       "model-version" : "1.0",
+                       "model-name" : "routing-instance"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/secondary-filter-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/secondary-filter-1.0.json
new file mode 100644 (file)
index 0000000..cef0a94
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "738ff299-6290-4c00-8998-bd0e96a07b93",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "1380619d-dd1a-4cec-b755-c6407833e065",
+                       "model-version" : "1.0",
+                       "model-name" : "secondary-filter"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/segmentation-assignment-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/segmentation-assignment-1.0.json
new file mode 100644 (file)
index 0000000..4335e10
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "6e814aee-46e1-4583-a9d4-0049bfd2b59b",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "c5171ae0-44fb-4c04-b482-d56702241a44",
+                       "model-version" : "1.0",
+                       "model-name" : "segmentation-assignment"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-1.0.json
new file mode 100644 (file)
index 0000000..ab3295a
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "07a3a60b-1b6c-4367-8173-8014386f89e3",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "ecce2c42-3957-4ae0-9442-54bc6afe27b6",
+                       "model-version" : "1.0",
+                       "model-name" : "service"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-capability-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-capability-1.0.json
new file mode 100644 (file)
index 0000000..038a993
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "b1a7cc05-d19d-443b-a5d1-733e325c4232",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "f9cfec1b-18da-4bba-bd83-4b26cca115cd",
+                       "model-version" : "1.0",
+                       "model-name" : "service-capability"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-instance-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-instance-1.0.json
new file mode 100644 (file)
index 0000000..b5ef861
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "82194af1-3c2c-485a-8f44-420e22a9eaa4",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "46b92144-923a-4d20-b85a-3cbd847668a9",
+                       "model-version" : "1.0",
+                       "model-name" : "service-instance"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-subscription-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/service-subscription-1.0.json
new file mode 100644 (file)
index 0000000..2af765f
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "2e1a602a-acd8-4f78-94ff-618b802a303b",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "5e68299a-79f2-4bfb-8fbc-2bae877a2459",
+                       "model-version" : "1.0",
+                       "model-name" : "service-subscription"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/site-pair-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/site-pair-1.0.json
new file mode 100644 (file)
index 0000000..eef13ea
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "db63f3e6-f8d1-484e-8d5e-191600b7914b",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "7106bc02-6552-4fc3-8a56-4f3df9034531",
+                       "model-version" : "1.0",
+                       "model-name" : "site-pair"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/site-pair-set-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/site-pair-set-1.0.json
new file mode 100644 (file)
index 0000000..3c77903
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "5d4dae3e-b402-4bfd-909e-ece12ff75d26",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "a5c6c1bc-dc38-468e-9459-bb08f87247df",
+                       "model-version" : "1.0",
+                       "model-name" : "site-pair-set"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/snapshot-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/snapshot-1.0.json
new file mode 100644 (file)
index 0000000..24ea90b
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "24de00ef-aead-4b52-995b-0adf8d4bd90d",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "962a7c8b-687f-4d32-a775-fe098e214bcd",
+                       "model-version" : "1.0",
+                       "model-name" : "snapshot"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/sriov-vf-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/sriov-vf-1.0.json
new file mode 100644 (file)
index 0000000..a5c077a
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "04b2935f-33c4-40a9-8af0-8b52690042dc",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "1e8b331f-3d4a-4160-b7aa-f4d5a8916625",
+                       "model-version" : "1.0",
+                       "model-name" : "sriov-vf"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/start-node-filter-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/start-node-filter-1.0.json
new file mode 100644 (file)
index 0000000..743d89e
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "083093a3-e407-447a-ba5d-7583e4d23e1d",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "aad96fd3-e75f-42fc-9777-3450c36f1168",
+                       "model-version" : "1.0",
+                       "model-name" : "start-node-filter"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/subnet-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/subnet-1.0.json
new file mode 100644 (file)
index 0000000..f6b2e55
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "1b2c9ba7-e449-4831-ba15-3073672f5ef2",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "f902a6bc-6be4-4fe5-8458-a6ec0056b374",
+                       "model-version" : "1.0",
+                       "model-name" : "subnet"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/tagged-inventory-item-list-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/tagged-inventory-item-list-1.0.json
new file mode 100644 (file)
index 0000000..5146b99
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "e78a7eaa-f65d-4919-9c2b-5b258c8c4d7e",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "c246f6e2-e3a1-4697-94c0-5672a7fbbf04",
+                       "model-version" : "1.0",
+                       "model-name" : "tagged-inventory-item-list"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/tenant-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/tenant-1.0.json
new file mode 100644 (file)
index 0000000..e105783
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "97c26c99-6870-44c1-8a07-1d900d3f4ce6",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "abcc54bc-bb74-49dc-9043-7f7171707545",
+                       "model-version" : "1.0",
+                       "model-name" : "tenant"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/tunnel-xconnect-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/tunnel-xconnect-1.0.json
new file mode 100644 (file)
index 0000000..5c6d5c6
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "50b9e2fa-005c-4bbe-b651-3251dece4cd8",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "e7cb4ca8-e1a5-4487-a716-4ae0bcd8aef5",
+                       "model-version" : "1.0",
+                       "model-name" : "tunnel-xconnect"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/update-node-key-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/update-node-key-1.0.json
new file mode 100644 (file)
index 0000000..25c5efd
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "fe81c801-f65d-408a-b2b7-a729a18f8154",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "6004cfa6-eb6d-4062-971f-b1fde6b74aa0",
+                       "model-version" : "1.0",
+                       "model-name" : "update-node-key"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vce-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vce-1.0.json
new file mode 100644 (file)
index 0000000..45f01d4
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "bab6dceb-e7e6-4301-a5e0-a7399b48d792",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "b6cf54b5-ec45-43e1-be64-97b4e1513333",
+                       "model-version" : "1.0",
+                       "model-name" : "vce"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vf-module-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vf-module-1.0.json
new file mode 100644 (file)
index 0000000..383d187
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "ef86f9c5-2165-44f3-8fc3-96018b609ea5",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "c00563ae-812b-4e62-8330-7c4d0f47088a",
+                       "model-version" : "1.0",
+                       "model-name" : "vf-module"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vig-server-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vig-server-1.0.json
new file mode 100644 (file)
index 0000000..6fd8d24
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "bed7c3b7-35d0-4cd9-abde-41b20e68b28e",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "8e8c22f1-fbdf-48ea-844c-8bdeb44e7b16",
+                       "model-version" : "1.0",
+                       "model-name" : "vig-server"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/virtual-data-center-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/virtual-data-center-1.0.json
new file mode 100644 (file)
index 0000000..a36361e
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "5150abcf-0c5f-4593-9afe-a19c48fc4824",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "6dd43ced-d789-47af-a759-d3abc14e3ac1",
+                       "model-version" : "1.0",
+                       "model-name" : "virtual-data-center"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vlan-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vlan-1.0.json
new file mode 100644 (file)
index 0000000..64608f8
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "d2b1eaf1-ae59-4116-9ee4-aa0179faa4f8",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "257d88a5-a269-4c35-944f-aca04fbdb791",
+                       "model-version" : "1.0",
+                       "model-name" : "vlan"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vnf-image-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vnf-image-1.0.json
new file mode 100644 (file)
index 0000000..1756e38
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "f9a628ff-7aa0-40e2-a93d-02d91c950982",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "c4d3e747-ba4a-4b17-9896-94c6f18c19d3",
+                       "model-version" : "1.0",
+                       "model-name" : "vnf-image"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vnfc-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vnfc-1.0.json
new file mode 100644 (file)
index 0000000..8c663a7
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "96129eb9-f0de-4e05-8af2-73146473f766",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "5761e0a7-c6df-4d8a-9ebd-b8f445054dec",
+                       "model-version" : "1.0",
+                       "model-name" : "vnfc"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/volume-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/volume-1.0.json
new file mode 100644 (file)
index 0000000..dd5d239
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "ddd739b4-2b25-46c4-affc-41a32af5cc42",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "0fbe2e8f-4d91-4415-a772-88387049b38d",
+                       "model-version" : "1.0",
+                       "model-name" : "volume"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/volume-group-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/volume-group-1.0.json
new file mode 100644 (file)
index 0000000..4ccde3a
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "fcec1b02-b2d0-4834-aef8-d71be04717dd",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "99d44c90-1f61-4418-b9a6-56586bf38c79",
+                       "model-version" : "1.0",
+                       "model-name" : "volume-group"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vpe-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vpe-1.0.json
new file mode 100644 (file)
index 0000000..ed5017e
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "053ec3a7-5b72-492d-b54d-123805a9b967",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "203817d3-829c-42d4-942d-2a935478e993",
+                       "model-version" : "1.0",
+                       "model-name" : "vpe"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vpls-pe-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vpls-pe-1.0.json
new file mode 100644 (file)
index 0000000..0d072bc
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "457ba89b-334c-4fbd-acc4-160ac0e0cdc0",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "b1566228-6785-4ce1-aea2-053736f80341",
+                       "model-version" : "1.0",
+                       "model-name" : "vpls-pe"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vpn-binding-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vpn-binding-1.0.json
new file mode 100644 (file)
index 0000000..e0439b6
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "9e23b675-db2b-488b-b459-57aa9857baa0",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "21a146e5-9901-448c-9197-723076770119",
+                       "model-version" : "1.0",
+                       "model-name" : "vpn-binding"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vserver-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/vserver-1.0.json
new file mode 100644 (file)
index 0000000..a069209
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "model-invariant-id" : "ff69d4e0-a8e8-4108-bdb0-dd63217e63c7",
+       "model-type" : "widget",
+       "model-vers" : {
+               "model-ver" : [ {
+                       "model-version-id" : "8ecb2c5d-7176-4317-a255-26274edfdd53",
+                       "model-version" : "1.0",
+                       "model-name" : "vserver"
+               } ]
+       }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/zone-1.0.json b/aai-traversal/bundleconfig-local/etc/scriptdata/widget-model-json/zone-1.0.json
new file mode 100644 (file)
index 0000000..8427ded
--- /dev/null
@@ -0,0 +1,11 @@
+{
+   "model-invariant-id" : "16f7cb93-e807-4065-816b-9cdf391d4992",
+   "model-type" : "widget",
+   "model-vers" : {
+      "model-ver" : [ {
+         "model-version-id" : "f7f21a66-4714-431c-af17-52d64e21de95",
+         "model-name" : "zone",
+         "model-version" : "1.0"
+      } ]
+   }
+}
diff --git a/aai-traversal/bundleconfig-local/etc/service-file-monitor.properties b/aai-traversal/bundleconfig-local/etc/service-file-monitor.properties
new file mode 100644 (file)
index 0000000..4d9bee9
--- /dev/null
@@ -0,0 +1,5 @@
+#This properties file is used for defining any file paths that you would like to have monitored.
+
+#user config file paths go here as (key-value) pairs. File extension will have to be either .properties or .json in order for it to be monitored. 
+#file1=/opt/app/yourService/file.properties
+
diff --git a/aai-traversal/bundleconfig-local/etc/sysprops/sys-props.properties b/aai-traversal/bundleconfig-local/etc/sysprops/sys-props.properties
new file mode 100644 (file)
index 0000000..13c97a9
--- /dev/null
@@ -0,0 +1,140 @@
+#This file is used for defining AJSC system properties for different configuration schemes and is necessary for the AJSC to run properly.
+#The sys-props.properties file is used for running locally. The template.sys-props.properties file will be used when deployed
+#to a SOA/CSI Cloud node.
+
+#AJSC System Properties. The following properties are required for ALL AJSC services. If you are adding System Properties for your
+#particular service, please add them AFTER all AJSC related System Properties. 
+
+#For Cadi Authorization, use value="authentication-scheme-1
+CadiAuthN=authentication-scheme-1
+
+#For Basic Authorization, use value="authentication-scheme-1
+authN=authentication-scheme-2
+
+#Persistence used for AJSC meta-data storage. For most environments, "file" should be used.
+ajscPersistence=file
+
+# If using hawtio for local development, these properties will allow for faster server startup and usage for local development
+hawtio.authenticationEnabled=false
+hawtio.config.pullOnStartup=false
+
+#Removes the extraneous restlet console output
+org.restlet.engine.loggerFacadeClass=org.restlet.ext.slf4j.Slf4jLoggerFacade
+
+#server.host property to be enabled for local DME2 related testing
+#server.host=<Your network IP address> 
+
+#Enable/disable SSL (values=true/false). This property also determines which protocol to use (https if true, http otherwise), to register services into GRM through DME2.
+enableSSL=false
+
+#Enable/disable csi logging (values=true/false). This can be disabled during local development
+csiEnable=false
+
+#Enable/disable EJB Container
+ENABLE_EJB=false
+
+#Enable/disable OSGI
+isOSGIEnable=false
+
+#Configure JMS Queue (WMQ/TIBCO)
+JMS_BROKER=WMQ
+
+#JMS properties needed for CSI Logging
+JMS_TIBCO_PROVIDER_URL=ONAPserverTBD
+JMS_LOGGER_USER_NAME=spm2
+JMS_LOGGER_PASSWORD=its4test
+JMS_LOGGER_AUDIT_QUEUE_BINDING=pub.m2e.audit.logger.queue
+JMS_LOGGER_PERF_QUEUE_BINDING=log.csi.performance02
+
+#WMQ connectivity
+JMS_WMQ_PROVIDER_URL=aftdsc://AFTUAT/34.07/-84.28
+JMS_WMQ_CONNECTION_FACTORY_NAME=aftdsc://AFTUAT/?service=CSILOG,version=1.0,bindingType=fusionBus,envContext=Q,Q25A=YES
+JMS_WMQ_INITIAL_CONNECTION_FACTORY_NAME=com.att.aft.jms.FusionCtxFactory
+JMS_WMQ_AUDIT_DESTINATION_NAME=queue:///CSILOGQL.M2E.DASHBOARD01.NOT.Q25A
+JMS_WMQ_PERF_DESTINATION_NAME=queue:///CSILOGQL.M2E.PERFORMANCE01.NOT.Q25A
+
+
+#CSI related variables for CSM framework
+csm.hostname=d1a-m2e-q112m2e1.edc.cingular.net
+
+#Enable/disable endpoint level logging (values=true/false). This can be disabled during local development
+endpointLogging=false
+
+#SOA_CLOUD_ENV is used to register your service with dme2 and can be turned off for local development (values=true/false).
+SOA_CLOUD_ENV=false
+
+#CONTINUE_ON_LISTENER_EXCEPTION will exit the application if there is a DME2 exception at the time of registration.
+CONTINUE_ON_LISTENER_EXCEPTION=false
+
+#Jetty Container ThreadCount Configuration Variables
+AJSC_JETTY_ThreadCount_MIN=10
+AJSC_JETTY_ThreadCount_MAX=500
+AJSC_JETTY_IDLETIME_MAX=60000
+AJSC_JETTY_BLOCKING_QUEUE_SIZE=100
+
+#Camel Context level default threadPool Profile configuration
+CAMEL_POOL_SIZE=10
+CAMEL_MAX_POOL_SIZE=20
+CAMEL_KEEP_ALIVE_TIME=60
+CAMEL_MAX_QUEUE_SIZE=1000
+
+#File Monitor configurations
+ssf_filemonitor_polling_interval=5
+ssf_filemonitor_threadpool_size=10
+
+#GRM/DME2 System Properties
+AFT_DME2_CONN_IDLE_TIMEOUTMS=5000
+AJSC_ENV=SOACLOUD
+
+SOACLOUD_NAMESPACE=com.att.ajsc
+SOACLOUD_ENV_CONTEXT=DEV
+SOACLOUD_PROTOCOL=http
+SOACLOUD_ROUTE_OFFER=DEFAULT
+
+sslport=8446
+server.port=8083
+
+AFT_LATITUDE=23.4
+AFT_LONGITUDE=33.6
+AFT_ENVIRONMENT=AFTUAT
+
+#Restlet Component Default Properties
+RESTLET_COMPONENT_CONTROLLER_DAEMON=true
+RESTLET_COMPONENT_CONTROLLER_SLEEP_TIME_MS=100
+RESTLET_COMPONENT_INBOUND_BUFFER_SIZE=8192
+RESTLET_COMPONENT_MIN_THREADS=1
+RESTLET_COMPONENT_MAX_THREADS=10
+RESTLET_COMPONENT_LOW_THREADS=8
+RESTLET_COMPONENT_MAX_QUEUED=0
+RESTLET_COMPONENT_MAX_CONNECTIONS_PER_HOST=-1
+RESTLET_COMPONENT_MAX_TOTAL_CONNECTIONS=-1
+RESTLET_COMPONENT_OUTBOUND_BUFFER_SIZE=8192
+RESTLET_COMPONENT_PERSISTING_CONNECTIONS=true
+RESTLET_COMPONENT_PIPELINING_CONNECTIONS=false
+RESTLET_COMPONENT_THREAD_MAX_IDLE_TIME_MS=60000
+RESTLET_COMPONENT_USE_FORWARDED_HEADER=false
+RESTLET_COMPONENT_REUSE_ADDRESS=true
+
+#Externalized jar and properties file location. In CSI environments, there are a few libs that have been externalized to aid
+#in CSTEM maintenance of the versions of these libs. The most important to the AJSC is the DME2 lib. Not only is this lib necessary
+#for proper registration of your AJSC service on a node, but it is also necessary for running locally as well. Another framework
+#used in CSI envs is the CSM framework. These 2 framework libs are shown as "provided" dependencies within the pom.xml. These
+#dependencies will be copied into the target/commonLibs folder with the normal "mvn clean package" goal of the AJSC. They will
+#then be added to the classpath via AJSC_EXTERNAL_LIB_FOLDERS system property. Any files (mainly property files) that need
+#to be on the classpath should be added to the AJSC_EXTERNAL_PROPERTIES_FOLDERS system property. The default scenario when 
+#testing your AJSC service locally will utilize the target/commonLibs directory for DME2 and CSM related artifacts and 2 
+#default csm properties files will be used for local testing with anything CSM knorelated.
+#NOTE: we are using maven-replacer-plugin to replace "(doubleUnderscore)basedir(doubleUnderscore)" with ${basedir} within the 
+#target directory for running locally. Multiple folder locations can be separated by the pipe ("|") character.
+#Please, NOTE: for running locally, we are setting this system property in the antBuild/build.xml "runLocal" target and in the 
+#"runAjsc" profile within the pom.xml. This is to most effectively use maven variables (${basedir}, most specifically. Therefore,
+#when running locally, the following 2 properties should be set within the profile(s) themselves. 
+#Example: target/commonLibs|target/otherLibs
+#AJSC_EXTERNAL_LIB_FOLDERS=__basedir__/target/commonLibs
+#AJSC_EXTERNAL_PROPERTIES_FOLDERS=__basedir__/ajsc-shared-config/etc
+#End of AJSC System Properties
+
+#Service System Properties. Please, place any Service related System Properties below.
+KEY_STORE_PASSWORD=OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0
+KEY_MANAGER_PASSWORD=OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0
+AAI_CORE_VERSION=1.1.0-SNAPSHOT
diff --git a/aai-traversal/bundleconfig-local/etc/sysprops/template.sys-props.properties b/aai-traversal/bundleconfig-local/etc/sysprops/template.sys-props.properties
new file mode 100644 (file)
index 0000000..778ac62
--- /dev/null
@@ -0,0 +1,115 @@
+#This file is used for defining AJSC system properties for different configuration schemes and is necessary for the AJSC to run properly.
+#The sys-props.properties file is used for running locally.
+
+#For Cadi Authorization, use value="authentication-scheme-1"
+CadiAuthN=__AJSC_CADI_AUTHN__
+
+#For Basic Authorization, use value="authentication-scheme-1"
+authN=__AJSC_AUTH_SCHEME__
+
+#Persistence used for AJSC meta-data storage. For most environments, "file" should be used.
+ajscPersistence=__AJSC_PERSISTENCE__
+
+#Configure externalized logback location
+logback.configurationFile=__LOGBACK_CONFIG_FILE__
+
+# If using hawtio for local development, these properties will allow for faster server startup and usage for local development.
+# You may wish to deploy hawtio.war to dev/test environments to help debugging as well, but should not be used in PROD env.
+hawtio.authenticationEnabled=__HAWTIO_AUTHENTICATION_ENABLED__
+hawtio.config.pullOnStartup=__HAWTIO_CONFIG_PULLONSTARTUP__
+
+#Removes the extraneous restlet console output
+org.restlet.engine.loggerFacadeClass=org.restlet.ext.slf4j.Slf4jLoggerFacade
+
+#Enable/disable SSL (values=true/false).
+enableSSL=__AJSC_ENABLE_SSL__
+
+#Enable/disable csi logging (values=true/false).
+csiEnable=__CSI_ENABLE__
+
+#Enable/disable EJB Container
+ENABLE_EJB=__ENABLE_EJB__
+
+#Enable/disable OSGI
+isOSGIEnable=__OSGI_ENABLE__
+
+#Configure JMS Queue (WMQ/TIBCO)
+JMS_BROKER=WMQ
+
+#JMS properties needed for CSI Logging
+JMS_TIBCO_PROVIDER_URL=ONAPserverTBD
+JMS_LOGGER_USER_NAME=spm2
+JMS_LOGGER_PASSWORD=
+JMS_LOGGER_AUDIT_QUEUE_BINDING=pub.m2e.audit.logger.queue
+JMS_LOGGER_PERF_QUEUE_BINDING=log.csi.performance02
+
+#WMQ connectivity
+JMS_WMQ_PROVIDER_URL=__JMS_WMQ_PROVIDER_URL__
+JMS_WMQ_CONNECTION_FACTORY_NAME=__JMS_WMQ_CONNECTION_FACTORY_NAME__
+JMS_WMQ_INITIAL_CONNECTION_FACTORY_NAME=__JMS_WMQ_INITIAL_CONNECTION_FACTORY_NAME__
+JMS_WMQ_AUDIT_DESTINATION_NAME=__JMS_WMQ_AUDIT_DESTINATION_NAME__ 
+JMS_WMQ_PERF_DESTINATION_NAME=__JMS_WMQ_PERF_DESTINATION_NAME__
+
+#CSI related variables for CSM framework
+csm.hostname=d1a-m2e-q112m2e1.edc.cingular.net
+
+#Enable/disable endpoint level logging (values=true/false). 
+endpointLogging=__END_POINT_LEVEL_LOGGING__
+
+#SOA_CLOUD_ENV is used to register your service with dme2 (values=true/false).
+SOA_CLOUD_ENV=__SOA_CLOUD_ENV__
+
+#Jetty Container ThreadCount Configuration Variables
+AJSC_JETTY_ThreadCount_MAX=__AJSC_JETTY_ThreadCount_MAX__
+AJSC_JETTY_ThreadCount_MIN=__AJSC_JETTY_ThreadCount_MIN__
+AJSC_JETTY_IDLETIME_MAX=__AJSC_JETTY_IDLETIME_MAX__
+AJSC_SERVICE_NAMESPACE=ActiveAndAvailableInventory-Traversal
+AJSC_SERVICE_VERSION=__AJSC_SERVICE_VERSION__
+AJSC_JETTY_BLOCKING_QUEUE_SIZE=100
+
+#Camel Context level default threadPool Profile configuration
+CAMEL_POOL_SIZE=__CAMEL_POOL_SIZE__
+CAMEL_MAX_POOL_SIZE=__CAMEL_MAX_POOL_SIZE__
+CAMEL_KEEP_ALIVE_TIME=__CAMEL_KEEP_ALIVE_TIME__
+CAMEL_MAX_QUEUE_SIZE=__CAMEL_MAX_QUEUE_SIZE__
+
+#File Monitor configurations
+ssf_filemonitor_polling_interval=__AJSC_SSF_FILE_MONITOR_POLLING_INTERVAL__
+ssf_filemonitor_threadpool_size=__AJSC_SSF_FILE_MONITOR_THREAD_POOL_SIZE__
+
+#GRM/DME2 System Properties below
+AFT_DME2_CONN_IDLE_TIMEOUTMS=__AFT_DME2_CONN_IDLE_TIMEOUTMS__
+AJSC_ENV=__AJSC_ENV__
+SOACLOUD_NAMESPACE=__SOA_CLOUD_NAMESPACE__
+SOACLOUD_ENV_CONTEXT=__SCLD_ENV__
+SOACLOUD_PROTOCOL=__SOACLOUD_PROTOCOL__
+SOACLOUD_ROUTE_OFFER=__AAIENV__
+sslport=8446
+server.port=8083
+AFT_LATITUDE=__LATITUDE__
+AFT_LONGITUDE=__LONGITUDE__
+AFT_ENVIRONMENT=__AFT_ENVIRONMENT__
+
+#Restlet Component Properties
+RESTLET_COMPONENT_CONTROLLER_DAEMON=__RESTLET_COMPONENT_CONTROLLER_DAEMON__
+RESTLET_COMPONENT_CONTROLLER_SLEEP_TIME_MS=__RESTLET_COMPONENT_CONTROLLER_SLEEP_TIME_MS__
+RESTLET_COMPONENT_INBOUND_BUFFER_SIZE=__RESTLET_COMPONENT_INBOUND_BUFFER_SIZE__
+RESTLET_COMPONENT_MIN_THREADS=__RESTLET_COMPONENT_MIN_THREADS__
+RESTLET_COMPONENT_MAX_THREADS=__RESTLET_COMPONENT_MAX_THREADS__
+RESTLET_COMPONENT_LOW_THREADS=__RESTLET_COMPONENT_LOW_THREADS__
+RESTLET_COMPONENT_MAX_QUEUED=__RESTLET_COMPONENT_MAX_QUEUED__
+RESTLET_COMPONENT_MAX_CONNECTIONS_PER_HOST=__RESTLET_COMPONENT_MAX_CONNECTIONS_PER_HOST__
+RESTLET_COMPONENT_MAX_TOTAL_CONNECTIONS=__RESTLET_COMPONENT_MAX_TOTAL_CONNECTIONS__
+RESTLET_COMPONENT_OUTBOUND_BUFFER_SIZE=__RESTLET_COMPONENT_OUTBOUND_BUFFER_SIZE__
+RESTLET_COMPONENT_PERSISTING_CONNECTIONS=__RESTLET_COMPONENT_PERSISTING_CONNECTIONS__
+RESTLET_COMPONENT_PIPELINING_CONNECTIONS=__RESTLET_COMPONENT_PIPELINING_CONNECTIONS__
+RESTLET_COMPONENT_THREAD_MAX_IDLE_TIME_MS=__RESTLET_COMPONENT_THREAD_MAX_IDLE_TIME_MS__
+RESTLET_COMPONENT_USE_FORWARDED_HEADER=__RESTLET_COMPONENT_USE_FORWARDED_HEADER__
+RESTLET_COMPONENT_REUSE_ADDRESS=__RESTLET_COMPONENT_REUSE_ADDRESS__
+
+AJSC_EXTERNAL_LIB_FOLDERS=__CSM_LIB__|__DME2_LIB__|__AJSC_EXTERNAL_LIB_FOLDERS__
+AJSC_EXTERNAL_PROPERTIES_FOLDERS=__AJSC_SHARED_CONFIG__|__AJSC_EXTERNAL_PROPERTIES_FOLDERS__
+
+KEY_STORE_PASSWORD=__KEY_STORE_PASSWORD__
+KEY_MANAGER_PASSWORD=__KEY_MANAGER_PASSWORD__
+AAI_CORE_VERSION=1.1.0-SNAPSHOT
diff --git a/aai-traversal/bundleconfig-local/symlinks.txt b/aai-traversal/bundleconfig-local/symlinks.txt
new file mode 100644 (file)
index 0000000..70f2c0d
--- /dev/null
@@ -0,0 +1,6 @@
+#This file provides the definitions of sym-links to CSTEM that will be used by your project once installed on a CSI node.
+
+link_jre=ajsc-shared-config
+link_csi-csm=ajsc-shared-config
+link_csi-dme=ajsc-shared-config
+link_introscope=ajsc-shared-config
diff --git a/aai-traversal/pom.xml b/aai-traversal/pom.xml
new file mode 100644 (file)
index 0000000..1423572
--- /dev/null
@@ -0,0 +1,695 @@
+<?xml version="1.0"?>
+<project
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+       xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>org.openecomp.aai</groupId>
+               <artifactId>traversal</artifactId>
+               <version>1.1.0-SNAPSHOT</version>
+       </parent>
+       <artifactId>aai-traversal</artifactId>
+       <name>aai-traversal</name>
+       <url>http://maven.apache.org</url>
+       <properties>
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <dockerLocation>${basedir}/target/swm/package/nix/dist_files/</dockerLocation>
+               <maven.build.timestamp.format>yyyyMMdd'T'HHmmss</maven.build.timestamp.format>
+               <docker.image.version>1.0.0</docker.image.version>
+               <aai-core.version>1.1.0-SNAPSHOT</aai-core.version>
+               <aai-schema.version>1.1.0-SNAPSHOT</aai-schema.version>
+               <hbase.version>1.0.2</hbase.version>
+               <sonar.language>java</sonar.language>
+               <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
+               <sonar.surefire.reportsPath>${project.build.directory}/surefire-reports</sonar.surefire.reportsPath>
+               <sonar.jacoco.reportPath>${project.build.directory}/coverage-reports/jacoco.exec</sonar.jacoco.reportPath>
+               <sonar.jacoco.reportMissing.force.zero>false</sonar.jacoco.reportMissing.force.zero>
+               <sonar.projectVersion>${project.version}</sonar.projectVersion>
+               <!-- old version 
+                       <hbase.version>0.98.4-hadoop2</hbase.version> 
+               -->
+       </properties>
+       <dependencies>
+               <dependency>
+                       <groupId>org.openecomp.aai</groupId>
+                       <artifactId>aai-schema</artifactId>
+                       <version>${aai-schema.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.openecomp.aai</groupId>
+                       <artifactId>aai-core</artifactId>
+                       <version>${aai-core.version}</version>
+               </dependency>
+               <!-- Scamper related dependencies -->
+               <dependency>
+                       <groupId>com.rabbitmq</groupId>
+                       <artifactId>amqp-client</artifactId>
+                       <version>3.6.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>log4j</groupId>
+                       <artifactId>apache-log4j-extras</artifactId>
+                       <version>1.2.17</version>
+                       <exclusions>
+                               <exclusion>
+                                       <artifactId>log4j</artifactId>
+                                       <groupId>log4j</groupId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+
+               <dependency>
+                       <groupId>commons-beanutils</groupId>
+                       <artifactId>commons-beanutils</artifactId>
+                       <version>1.9.2</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.apache.commons</groupId>
+                       <artifactId>commons-compress</artifactId>
+                       <version>1.10</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>commons-configuration</groupId>
+                       <artifactId>commons-configuration</artifactId>
+                       <version>1.9</version>
+                       <exclusions>
+                               <exclusion>
+                                       <artifactId>commons-lang</artifactId>
+                                       <groupId>commons-lang</groupId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+
+               <dependency>
+                       <groupId>com.googlecode.java-diff-utils</groupId>
+                       <artifactId>diffutils</artifactId>
+                       <version>1.3.0</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.codehaus.jackson</groupId>
+                       <artifactId>jackson-core-asl</artifactId>
+                       <version>1.9.13</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.codehaus.jackson</groupId>
+                       <artifactId>jackson-mapper-asl</artifactId>
+                       <version>1.9.13</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpmime</artifactId>
+                       <version>4.5.2</version>
+               </dependency>
+
+               <!-- AJSC related dependencies -->
+               <dependency>
+                       <groupId>com.att.ajsc</groupId>
+                       <artifactId>ajsc-runner</artifactId>
+                       <version>${ajscRuntimeVersion}</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.att.ajsc</groupId>
+                       <artifactId>ajsc-core</artifactId>
+                       <version>${ajscRuntimeVersion}</version>
+                       <scope>provided</scope>
+               </dependency>
+
+               <!-- For dom4j dependency ONLY! - If deploying to CSI env, remove "provided"
+                       scope. In CSI env, this jar MUST be included within service project's swm 
+                       package -->
+               <dependency>
+                       <groupId>dom4j</groupId>
+                       <artifactId>dom4j</artifactId>
+                       <version>1.6.1</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>commons-lang</groupId>
+                       <artifactId>commons-lang</artifactId>
+                       <version>2.6</version>
+               </dependency>
+
+               <!-- eelf dependency -->
+               <dependency>
+                       <groupId>com.att.eelf</groupId>
+                       <artifactId>eelf-core</artifactId>
+                       <version>1.0.0</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>ch.qos.logback</groupId>
+                       <artifactId>logback-core</artifactId>
+                       <version>1.1.7</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>ch.qos.logback</groupId>
+                       <artifactId>logback-classic</artifactId>
+                       <version>1.1.7</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>ch.qos.logback</groupId>
+                       <artifactId>logback-access</artifactId>
+                       <version>1.1.7</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.hamcrest</groupId>
+                       <artifactId>hamcrest-junit</artifactId>
+                       <version>2.0.0.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.codehaus.janino</groupId>
+                       <artifactId>janino</artifactId>
+                       <version>2.7.8</version>
+               </dependency>
+               <dependency>
+                       <groupId>commons-collections</groupId>
+                       <artifactId>commons-collections</artifactId>
+               </dependency>
+
+               <dependency>
+                       <groupId>jdk.tools</groupId>
+                       <artifactId>jdk.tools</artifactId>
+                       <version>1.8.0_101</version>
+                       <scope>system</scope>
+                       <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
+               </dependency>
+
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.google.guava</groupId>
+                       <artifactId>guava</artifactId>
+                       <version>16.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.thinkaurelius.titan</groupId>
+                       <artifactId>titan-core</artifactId>
+                       <version>1.0.0</version>
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.slf4j</groupId>
+                                       <artifactId>slf4j-log4j12</artifactId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+               <dependency>
+                       <groupId>com.thinkaurelius.titan</groupId>
+                       <artifactId>titan-cassandra</artifactId>
+                       <version>1.0.0</version>
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.slf4j</groupId>
+                                       <artifactId>slf4j-log4j12</artifactId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+               <dependency>
+                       <groupId>com.thinkaurelius.titan</groupId>
+                       <artifactId>titan-hbase</artifactId>
+                       <version>1.0.0</version>
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.slf4j</groupId>
+                                       <artifactId>slf4j-log4j12</artifactId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+
+               <dependency>
+                       <groupId>org.apache.tinkerpop</groupId>
+                       <artifactId>gremlin-driver</artifactId>
+                       <version>3.0.1-incubating</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.hbase</groupId>
+                       <artifactId>hbase-client</artifactId>
+                       <version>${hbase.version}</version>
+                       <exclusions>
+                               <exclusion>
+                                       <groupId>org.slf4j</groupId>
+                                       <artifactId>slf4j-log4j12</artifactId>
+                               </exclusion>
+                               <exclusion>
+                                       <artifactId>log4j</artifactId>
+                                       <groupId>log4j</groupId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.hbase</groupId>
+                       <artifactId>hbase-protocol</artifactId>
+                       <version>${hbase.version}</version>
+                       <exclusions>
+                               <exclusion>
+                                       <artifactId>log4j</artifactId>
+                                       <groupId>log4j</groupId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.hbase</groupId>
+                       <artifactId>hbase-common</artifactId>
+                       <version>${hbase.version}</version>
+                       <exclusions>
+                               <exclusion>
+                                       <artifactId>log4j</artifactId>
+                                       <groupId>log4j</groupId>
+                               </exclusion>
+                       </exclusions>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.jersey</groupId>
+                       <artifactId>jersey-json</artifactId>
+                       <version>1.18</version>
+               </dependency>
+               <dependency>
+                       <groupId>jivesoftware</groupId>
+                       <artifactId>smack</artifactId>
+                       <version>3.0.4</version>
+               </dependency>
+
+               <dependency>
+                       <groupId>com.fasterxml.jackson.jaxrs</groupId>
+                       <artifactId>jackson-jaxrs-json-provider</artifactId>
+                       <version>2.1.4</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.googlecode.json-simple</groupId>
+                       <artifactId>json-simple</artifactId>
+                       <version>1.1.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.jersey</groupId>
+                       <artifactId>jersey-client</artifactId>
+                       <version>1.18</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-web</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.ws</groupId>
+                       <artifactId>spring-ws</artifactId>
+                       <version>1.5.2</version>
+                       <!--<version>2.1.3-RELEASE</version> -->
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>spring-core</artifactId>
+                       <version>4.2.5.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.mockito</groupId>
+                       <artifactId>mockito-all</artifactId>
+                       <version>1.10.19</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-junit4</artifactId>
+                       <version>1.6.2</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-api-mockito</artifactId>
+                       <version>1.6.2</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.beust</groupId>
+                       <artifactId>jcommander</artifactId>
+                       <version>1.48</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.json</groupId>
+                       <artifactId>json</artifactId>
+                       <version>20090211</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.freemarker</groupId>
+                       <artifactId>freemarker</artifactId>
+                       <version>2.3.14</version>
+               </dependency>
+               <dependency>
+                       <groupId>javax.xml.bind</groupId>
+                       <artifactId>jaxb-api</artifactId>
+                       <version>2.2.11</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.xml.bind</groupId>
+                       <artifactId>jaxb-impl</artifactId>
+                       <version>2.2.11</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.xml.bind</groupId>
+                       <artifactId>jaxb-core</artifactId>
+                       <version>2.2.11</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.sun.xml.bind</groupId>
+                       <artifactId>jaxb-xjc</artifactId>
+                       <version>2.2.11</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.eclipse.persistence</groupId>
+                       <artifactId>eclipselink</artifactId>
+                       <version>2.6.2</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.eclipse.persistence</groupId>
+                       <artifactId>org.eclipse.persistence.moxy</artifactId>
+                       <version>2.6.2</version>
+                       <scope>compile</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-javaagent</artifactId>
+                       <version>1.6.2</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.powermock</groupId>
+                       <artifactId>powermock-module-junit4-rule-agent</artifactId>
+                       <version>1.6.2</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.github.fge</groupId>
+                       <artifactId>json-patch</artifactId>
+                       <version>1.9</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.javatuples</groupId>
+                       <artifactId>javatuples</artifactId>
+                       <version>1.2</version>
+                       <scope>compile</scope>
+               </dependency>
+               <dependency>
+                       <groupId>com.google.code.gson</groupId>
+                       <artifactId>gson</artifactId>
+                       <version>2.7</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.att.nsa</groupId>
+                       <artifactId>dmaapClient</artifactId>
+                       <version>0.2.13</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.httpcomponents</groupId>
+                       <artifactId>httpcore</artifactId>
+                       <version>4.4</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.bazaarvoice.jolt</groupId>
+                       <artifactId>jolt-complete</artifactId>
+                       <version>0.0.24</version>
+               </dependency>
+               <dependency>
+                       <groupId>com.jayway.jsonpath</groupId>
+                       <artifactId>json-path</artifactId>
+                       <version>2.0.0</version>
+               </dependency>
+       </dependencies>
+       <build>
+               <finalName>traversal</finalName>
+               <pluginManagement>
+                       <plugins>
+                               <plugin>
+                                       <groupId>org.jsonschema2pojo</groupId>
+                                       <artifactId>jsonschema2pojo-maven-plugin</artifactId>
+                                       <version>0.4.13</version>
+                                       <configuration>
+                                               <sourceType>jsonschema</sourceType>
+                                               <sourceDirectory>src/main/resources/json</sourceDirectory>
+                                               <outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
+                                               <annotationStyle>jackson2</annotationStyle>
+                                               <generateBuilders>true</generateBuilders>
+                                       </configuration>
+                               </plugin>
+                               <plugin>
+                                       <groupId>org.apache.maven.plugins</groupId>
+                                       <artifactId>maven-dependency-plugin</artifactId>
+                                       <version>2.8</version>
+                                       <executions>
+                                               <execution>
+                                                       <id>copy-agent</id>
+                                                       <phase>process-test-classes</phase>
+                                                       <goals>
+                                                               <goal>copy</goal>
+                                                       </goals>
+                                                       <configuration>
+                                                               <artifactItems>
+                                                                       <artifactItem>
+                                                                               <groupId>org.powermock</groupId>
+                                                                               <artifactId>powermock-module-javaagent</artifactId>
+                                                                               <version>1.6.2</version>
+                                                                               <outputDirectory>${project.build.directory}/agents</outputDirectory>
+                                                                               <destFileName>powermock-javaagent.jar</destFileName>
+                                                                       </artifactItem>
+                                                               </artifactItems>
+                                                       </configuration>
+                                               </execution>
+                                               <execution>
+                                                       <id>unpack-schema-dependency</id>
+                                                       <phase>initialize</phase>
+                                                       <goals>
+                                                               <goal>unpack</goal>
+                                                       </goals>
+                                               </execution>
+                                       </executions>
+                                       <configuration>
+                                               <artifactItems>
+                                                       <artifactItem>
+                                                               <groupId>org.openecomp.aai</groupId>
+                                                               <artifactId>aai-schema</artifactId>
+                                                               <version>${aai-schema.version}</version>
+                                                               <outputDirectory>bundleconfig-local/etc</outputDirectory>
+                                                               <includes>oxm/*.xml</includes>
+                                                       </artifactItem>
+                                               </artifactItems>
+                                               <!-- other configurations here -->
+                                       </configuration>
+                               </plugin>
+                               <plugin>
+                                       <groupId>org.apache.maven.plugins</groupId>
+                                       <artifactId>maven-surefire-plugin</artifactId>
+                                       <version>2.12.4</version>
+                                       <configuration>
+                                               <argLine>-javaagent:${project.build.directory}/agents/powermock-javaagent.jar
+                                                       -noverify</argLine>
+                                               <systemPropertyVariables>
+                                                       <AJSC_HOME>.</AJSC_HOME>
+                                                       <BUNDLECONFIG_DIR>bundleconfig-local</BUNDLECONFIG_DIR>
+                                               </systemPropertyVariables>
+                                       </configuration>
+                               </plugin>
+                               <plugin>
+                                       <groupId>org.codehaus.groovy.maven</groupId>
+                                       <artifactId>gmaven-plugin</artifactId>
+                                       <executions>
+                                               <execution>
+                                                       <phase>validate</phase>
+                                                       <goals>
+                                                               <goal>execute</goal>
+                                                       </goals>
+                                                       <configuration>
+                                                               <source>
+                                                                       println project.properties['aai.project.version'];
+                                                                       def versionArray;
+                                                                       if ( project.properties['aai.project.version'] != null ) {
+                                                                               versionArray = project.properties['aai.project.version'].split('\\.');
+                                                                       }
+
+                                                                       if ( project.properties['aai.project.version'].endsWith("-SNAPSHOT") ) {
+                                                                               project.properties['project.docker.latesttag.version']=versionArray[0] + '.' + versionArray[1] + "-SNAPSHOT-latest";
+                                                                       } else {
+                                                                               project.properties['project.docker.latesttag.version']=versionArray[0] + '.' + versionArray[1] + "-STAGING-latest";
+                                                                       }
+
+                                                                       println 'New Tag for docker:' + project.properties['project.docker.latesttag.version'];
+                                                               </source>
+                                                       </configuration>
+                                               </execution>
+                                       </executions>
+                               </plugin>
+                               <plugin>
+                                       <groupId>org.apache.maven.plugins</groupId>
+                                       <artifactId>maven-resources-plugin</artifactId>
+                                       <version>2.7</version>
+                                       <executions>
+                                               <execution>
+                                                       <id>copy-docker-file</id>
+                                                       <phase>package</phase>
+                                                       <goals>
+                                                               <goal>copy-resources</goal>
+                                                       </goals>
+                                                       <configuration>
+                                                               <outputDirectory>${dockerLocation}</outputDirectory>
+                                                               <overwrite>true</overwrite>
+                                                               <resources>
+                                                                       <resource>
+                                                                               <directory>${basedir}/src/main/resources/docker</directory>
+                                                                               <filtering>true</filtering>
+                                                                               <includes>
+                                                                                       <include>**/*</include>
+                                                                               </includes>
+                                                                       </resource>
+                                                               </resources>
+                                                       </configuration>
+                                               </execution>
+                                               <execution>
+                                                       <id>copy-commonlibs-file</id>
+                                                       <phase>package</phase>
+                                                       <goals>
+                                                               <goal>copy-resources</goal>
+                                                       </goals>
+                                                       <configuration>
+                                                               <outputDirectory>${dockerLocation}/commonLibs</outputDirectory>
+                                                               <overwrite>true</overwrite>
+                                                               <resources>
+                                                                       <resource>
+                                                                               <directory>${basedir}/target/commonLibs</directory>
+                                                                               <filtering>false</filtering>
+                                                                               <includes>
+                                                                                       <include>*.jar</include>
+                                                                               </includes>
+                                                                       </resource>
+                                                               </resources>
+                                                       </configuration>
+                                               </execution>
+                                       </executions>
+                               </plugin>
+                               <plugin>
+                                       <groupId>io.fabric8</groupId>
+                                       <artifactId>docker-maven-plugin</artifactId>
+                                       <version>0.16.5</version>
+                                       <configuration>
+                                               <verbose>true</verbose>
+                                               <apiVersion>1.23</apiVersion>
+                                               <images>
+                                                       <image>
+                                                               <name>${docker.push.registry}/openecomp/aai-traversal:%l</name>
+                                                               <build>
+                                                                       <tags>
+                                                                               <tag>${project.docker.latesttag.version}</tag>
+                                                                               <tag>${project.version}-STAGING-${maven.build.timestamp}</tag>
+                                                                       </tags>
+                                                                       <cleanup>try</cleanup>
+                                                                       <dockerFileDir>${dockerLocation}</dockerFileDir>
+                                                                       <dockerFile>${dockerLocation}/Dockerfile</dockerFile>
+                                                               </build>
+                                                       </image>
+                                               </images>
+                                       </configuration>
+                                       <executions>
+                                               <execution>
+                                                       <id>clean-images</id>
+                                                       <phase>pre-clean</phase>
+                                                       <goals>
+                                                               <goal>remove</goal>
+                                                       </goals>
+                                                       <configuration>
+                                                               <removeAll>true</removeAll>
+                                                               <image>openecomp/aai-traversal:%l</image>
+                                                       </configuration>
+                                               </execution>
+                                               <execution>
+                                                       <id>generate-images</id>
+                                                       <phase>generate-sources</phase>
+                                                       <goals>
+                                                               <goal>build</goal>
+                                                       </goals>
+                                               </execution>
+                                               <execution>
+                                                       <id>push-images</id>
+                                                       <phase>deploy</phase>
+                                                       <goals>
+                                                               <goal>build</goal>
+                                                               <goal>push</goal>
+                                                       </goals>
+                                                       <configuration>
+                                                               <image>openecomp/aai-traversal:%l</image>
+                                                       </configuration>
+                                               </execution>
+                                       </executions>
+                               </plugin>
+                       </plugins>
+               </pluginManagement>
+               <plugins>
+                       <plugin>
+                               <groupId>org.codehaus.mojo</groupId>
+                               <artifactId>sonar-maven-plugin</artifactId>
+                               <version>3.2</version>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.jacoco</groupId>
+                               <artifactId>jacoco-maven-plugin</artifactId>
+                               <version>0.7.7.201606060606</version>
+                               <configuration>
+                                       <dumpOnExit>true</dumpOnExit>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <id>jacoco-initialize-unit-tests</id>
+                                               <goals>
+                                                       <goal>prepare-agent</goal>
+                                               </goals>
+                                               <configuration>
+                                                       <destFile>${project.build.directory}/coverage-reports/jacoco.exec</destFile>
+                                                       <!-- <append>true</append> -->
+                                               </configuration>
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
+       </build>
+       <profiles>
+               <!-- Use this profile to run the AJSC locally. This profile can be successfully 
+                       shutdown WITHIN eclipse even in a Windows environment. Debugging is also 
+                       available with this profile. -->
+               <profile>
+                       <id>passwordGenerator</id>
+                       <build>
+                               <defaultGoal>initialize</defaultGoal>
+                               <plugins>
+                                       <plugin>
+                                               <groupId>org.codehaus.mojo</groupId>
+                                               <artifactId>exec-maven-plugin</artifactId>
+                                               <version>1.3.2</version>
+                                               <executions>
+                                                       <execution>
+                                                               <phase>initialize</phase>
+                                                               <goals>
+                                                                       <goal>java</goal>
+                                                               </goals>
+                                                               <configuration>
+                                                                       <mainClass>org.eclipse.jetty.util.security.Password</mainClass>
+                                                                       <arguments>
+                                                                               <argument>user</argument>
+                                                                               <argument>aaiDomain2</argument>
+                                                                       </arguments>
+                                                               </configuration>
+                                                       </execution>
+                                               </executions>
+                                               <configuration>
+                                                       <executable>java</executable>
+                                               </configuration>
+                                       </plugin>
+                               </plugins>
+                       </build>
+               </profile>
+
+       </profiles>
+</project>
diff --git a/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/conf/FileMonitorBeans.xml b/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/conf/FileMonitorBeans.xml
new file mode 100644 (file)
index 0000000..9e3e060
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+       <!--<bean-->
+               <!--class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />-->
+               <!---->
+       <!--<bean id="ServicePropertiesListener" class="org.openecomp.aai.ajsc_aai.filemonitor.ServicePropertiesListener" />-->
+       <!---->
+       <!--<bean id="ServicePropertiesMap" class="org.openecomp.aai.ajsc_aai.filemonitor.ServicePropertiesMap" />-->
+
+       <!--<bean id="ServicePropertyService" class="org.openecomp.aai.ajsc_aai.filemonitor.ServicePropertyService">-->
+               <!--<property name="loadOnStartup" value="false" />-->
+               <!--<property name="fileChangedListener" ref="ServicePropertiesListener" />-->
+               <!--<property name="filePropertiesMap" ref="ServicePropertiesMap" />-->
+               <!--<property name="ssfFileMonitorPollingInterval" value="15" />-->
+               <!--<property name="ssfFileMonitorThreadpoolSize" value="10" />-->
+       <!--</bean>-->
+</beans>
diff --git a/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/conf/jaxrsBeans.groovy b/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/conf/jaxrsBeans.groovy
new file mode 100644 (file)
index 0000000..4029d25
--- /dev/null
@@ -0,0 +1,26 @@
+beans{
+       xmlns cxf: "http://camel.apache.org/schema/cxf"
+       xmlns jaxrs: "http://cxf.apache.org/jaxrs"
+       xmlns util: "http://www.springframework.org/schema/util"
+
+       SearchProvider(org.openecomp.aai.rest.search.SearchProvider)
+       ModelAndNamedQueryRestProvider(org.openecomp.aai.rest.search.ModelAndNamedQueryRestProvider)
+       QueryConsumer(org.openecomp.aai.rest.QueryConsumer)
+
+       V3ThroughV7Retired(org.openecomp.aai.rest.retired.V3ThroughV7Consumer)
+       V7V8NamedQueries(org.openecomp.aai.rest.retired.V7V8NamedQueries)
+
+       EchoResponse(org.openecomp.aai.rest.util.EchoResponse)
+
+
+       util.list(id: 'jaxrsServices') {
+
+               ref(bean:'SearchProvider')
+               ref(bean:'ModelAndNamedQueryRestProvider')
+               ref(bean:'QueryConsumer')
+               ref(bean: 'V7V8NamedQueries')
+               ref(bean:'V3ThroughV7Retired')
+
+               ref(bean:'EchoResponse')
+       }
+}
\ No newline at end of file
diff --git a/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/conf/serviceBeans.xml b/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/conf/serviceBeans.xml
new file mode 100644 (file)
index 0000000..f4bc26a
--- /dev/null
@@ -0,0 +1,47 @@
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:task="http://www.springframework.org/schema/task" xmlns:jms="http://www.springframework.org/schema/jms"
+       xsi:schemaLocation="
+                  http://cxf.apache.org/core
+                  http://cxf.apache.org/schemas/core.xsd
+              http://www.springframework.org/schema/beans
+              http://www.springframework.org/schema/beans/spring-beans.xsd
+              http://www.springframework.org/schema/context
+          http://www.springframework.org/schema/context/spring-context-2.5.xsd
+          http://www.springframework.org/schema/task 
+          http://www.springframework.org/schema/task/spring-task-3.0.xsd
+          http://www.springframework.org/schema/jms
+                  http://www.springframework.org/schema/jms/spring-jms-4.1.xsd">
+
+       <!-- Your bean definitions goes here -->
+       <!-- <bean id="performanceLog" name="performanceLog" class="com.att.ajsc.csi.logging.PerformanceTracking" 
+               /> -->
+       <!-- <bean id="processRestletHeaders" name="processRestletHeaders" class="ajsc.restlet.ProcessRestletHeaders" 
+               /> -->
+       <bean id="servicePropsBean" name="servicePropsBean"
+               class="org.openecomp.aai.ajsc_aai.util.ServicePropertiesMapBean" />
+       <bean id="jsonProvider" class="org.openecomp.aai.restcore.CustomJacksonJaxBJsonProvider" />
+
+       <bean id="inInterceptor" class="org.openecomp.aai.interceptors.AAILogJAXRSInInterceptor" />
+       <bean id="outInterceptor" class="org.openecomp.aai.interceptors.AAILogJAXRSOutInterceptor" />
+       <cxf:bus bus="cxfBus">
+               <cxf:inInterceptors>
+                       <ref bean="inInterceptor" />
+               </cxf:inInterceptors>
+               <cxf:outInterceptors>
+                       <ref bean="outInterceptor" />
+               </cxf:outInterceptors>
+       </cxf:bus>
+       <context:component-scan base-package="org.openecomp.aai.tasks" />
+
+       <task:scheduler id="taskScheduler" pool-size="10" />
+       <task:executor id="taskExecutor" pool-size="10"
+               queue-capacity="5" />
+       <task:annotation-driven executor="taskExecutor"
+               scheduler="taskScheduler" />
+
+
+       
+
+</beans>               
\ No newline at end of file
diff --git a/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/docs/README.txt b/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/docs/README.txt
new file mode 100644 (file)
index 0000000..3707179
--- /dev/null
@@ -0,0 +1 @@
+Place any docs here that you want to access within the ajsc upon deployment of your service.
diff --git a/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/lib/README.txt b/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/lib/README.txt
new file mode 100644 (file)
index 0000000..639e21b
--- /dev/null
@@ -0,0 +1 @@
+3rd party JAR's needed by your jars (if any) for a ajsc deployment package go here...
\ No newline at end of file
diff --git a/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/props/module.props b/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/props/module.props
new file mode 100644 (file)
index 0000000..17ebc08
--- /dev/null
@@ -0,0 +1 @@
+EXAMPLE.PROPERTY=EXAMLE_VALUE
\ No newline at end of file
diff --git a/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/routes/aai.route b/aai-traversal/src/main/ajsc/ajsc-aai_v1/ajsc-aai/v1/routes/aai.route
new file mode 100644 (file)
index 0000000..6a86246
--- /dev/null
@@ -0,0 +1,4 @@
+<route xmlns="http://camel.apache.org/schema/spring" trace="true"> 
+       <from uri="att-dme2-servlet:///aai?matchOnUriPrefix=true" />
+       <to uri="cxfbean:jaxrsServices?providers=#jsonProvider&amp;bus=#cxfBus" />
+</route>
\ No newline at end of file
diff --git a/aai-traversal/src/main/assemble/ajsc_module_assembly.xml b/aai-traversal/src/main/assemble/ajsc_module_assembly.xml
new file mode 100644 (file)
index 0000000..4ec4e28
--- /dev/null
@@ -0,0 +1,66 @@
+<assembly
+       xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+       <id>${version}</id>
+       <includeBaseDirectory>false</includeBaseDirectory>
+       <formats>
+               <format>zip</format>
+       </formats>
+       <fileSets>
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/routes/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/routes/</outputDirectory>
+                       <includes>
+                               <include>*.route</include>
+                       </includes>
+
+               </fileSet>
+
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/docs/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/docs/</outputDirectory>
+                       <includes>
+                               <include>*.*</include>
+                               <!-- <include>*.vm</include>  -->
+                       </includes>
+
+               </fileSet>
+
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/lib/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/lib/</outputDirectory>
+                       <includes>
+                               <include>*.jar</include>
+                       </includes>
+
+               </fileSet>
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/extJars/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/extJars/</outputDirectory>
+                       <includes>
+                               <include>*.jar</include>
+                       </includes>
+               </fileSet>
+               
+               <!-- also try to grab outputs from the "jar" plugin's package phase -->
+               <fileSet>
+                       <directory>${project.basedir}/target/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/lib/</outputDirectory>
+                       <includes>
+                               <include>*.jar</include>
+                       </includes>
+               </fileSet>
+
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/conf/</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/conf/</outputDirectory>
+                       <includes>
+                               <include>*.*</include>
+                       </includes>
+
+               </fileSet>
+       </fileSets>
+
+</assembly>
+
diff --git a/aai-traversal/src/main/assemble/ajsc_props_assembly.xml b/aai-traversal/src/main/assemble/ajsc_props_assembly.xml
new file mode 100644 (file)
index 0000000..5b8a6fa
--- /dev/null
@@ -0,0 +1,23 @@
+<assembly
+       xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+       <id>${version}_properties</id>
+       <includeBaseDirectory>false</includeBaseDirectory>
+       <formats>
+               <format>zip</format>
+       </formats>
+       <fileSets>
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-ajsc/props</directory>
+                       <outputDirectory>${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/props/</outputDirectory>
+                       <includes>
+                               <include>*.props</include>
+                       </includes>
+
+               </fileSet>
+
+       </fileSets>
+
+</assembly>
+
diff --git a/aai-traversal/src/main/assemble/ajsc_runtime_assembly.xml b/aai-traversal/src/main/assemble/ajsc_runtime_assembly.xml
new file mode 100644 (file)
index 0000000..e37d366
--- /dev/null
@@ -0,0 +1,44 @@
+<assembly
+       xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+       <id>runtimeEnvironment</id>
+       <includeBaseDirectory>false</includeBaseDirectory>
+       <formats>
+               <format>zip</format>
+       </formats>
+       <fileSets>
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-runtime/context/</directory>
+                       <outputDirectory>runtime/context/</outputDirectory>
+                       <includes>
+                               <include>*.context</include>
+                       </includes>
+               </fileSet>
+               <fileSet>
+                       <directory>${project.basedir}/target/versioned-runtime/serviceProperties/</directory>
+                       <outputDirectory>runtime/serviceProperties/</outputDirectory>
+                       <includes>
+                               <include>*.props</include>
+                       </includes>
+               </fileSet><fileSet>
+                       <directory>${project.basedir}/target/versioned-runtime/shiroRole</directory>
+                       <outputDirectory>runtime/shiroRole/</outputDirectory>
+                       <includes>
+                               <include>*.json</include>
+                       </includes>
+               </fileSet><fileSet>
+                       <directory>${project.basedir}/target/versioned-runtime/shiroUser</directory>
+                       <outputDirectory>runtime/shiroUser/</outputDirectory>
+                       <includes>
+                               <include>*.json</include>
+                       </includes>
+               </fileSet><fileSet>
+                       <directory>${project.basedir}/target/versioned-runtime/shiroUserRole</directory>
+                       <outputDirectory>runtime/shiroUserRole</outputDirectory>
+                       <includes>
+                               <include>*.json</include>
+                       </includes>
+               </fileSet>
+       </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/aai-traversal/src/main/config/ajsc-jetty.xml b/aai-traversal/src/main/config/ajsc-jetty.xml
new file mode 100644 (file)
index 0000000..d7e60ed
--- /dev/null
@@ -0,0 +1,155 @@
+<?xml version="1.0"  encoding="UTF-8"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
+<Configure id="ajsc-server" class="org.eclipse.jetty.server.Server">
+       <!-- DO NOT REMOVE!!!! This is setting up the AJSC Context -->
+       <New id="ajscContext" class="org.eclipse.jetty.webapp.WebAppContext">
+               <Set name="contextPath"><SystemProperty name="AJSC_CONTEXT_PATH" /></Set>
+               <Set name="extractWAR">true</Set>
+               <Set name="tempDirectory"><SystemProperty name="AJSC_TEMP_DIR" /></Set>
+               <Set name="war"><SystemProperty name="AJSC_WAR_PATH" /></Set>
+               <Set name="descriptor"><SystemProperty name="AJSC_HOME" />/etc/runner-web.xml</Set>
+               <Set name="overrideDescriptor"><SystemProperty name="AJSC_HOME" />/etc/ajsc-override-web.xml</Set>
+               <Set name="throwUnavailableOnStartupException">true</Set>
+               <Set name="servletHandler">
+                       <New class="org.eclipse.jetty.servlet.ServletHandler">
+                               <Set name="startWithUnavailable">false</Set>
+                       </New>
+               </Set>
+               <Set name="extraClasspath">
+                       <SystemProperty name="AJSC_HOME" />/extJars/aai-core-<SystemProperty name="aai-core.version"/>.jar,
+                       <SystemProperty name="AJSC_HOME" />/extJars/traversal.jar,
+                       <SystemProperty name="AJSC_HOME" />/extJars/logback-core-1.1.7.jar,
+                       <SystemProperty name="AJSC_HOME" />/extJars/logback-access-1.1.7.jar,   
+                       <SystemProperty name="AJSC_HOME" />/extJars/eelf-core-1.0.0.jar,
+               <SystemProperty name="AJSC_HOME" />/extJars/slf4j-api-1.7.21.jar
+               </Set>
+       </New>
+       
+       <Set name="handler">
+               <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
+                       <Set name="handlers">
+                               <Array type="org.eclipse.jetty.server.Handler">
+                                       <Item>
+                                               <New id="Contexts"
+                                                       class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
+                                                       <Set name="Handlers">
+                                                               <Array type="org.eclipse.jetty.webapp.WebAppContext">
+                                                                       <Item>
+                                                                               <Ref refid="ajscContext" />
+                                                                       </Item>
+                                                               </Array>
+                                                       </Set>
+                                               </New>
+                                       </Item>
+                                       <!-- add a RequestLogHandler -->
+                                       <Item>
+                                               <New id="RequestLogHandler" class="org.eclipse.jetty.server.handler.RequestLogHandler">
+                                                 <Set name="requestLog">
+                                                       <New id="requestLogImpl" class="ch.qos.logback.access.jetty.RequestLogImpl">
+                                                          <Set name="fileName"><SystemProperty name="AJSC_HOME" />/bundleconfig/etc/localhost-access-logback.xml</Set>
+                                                       </New>   
+                                                 </Set>
+                                               </New>
+                                       </Item>
+                               </Array>
+                       </Set>
+               </New>
+       </Set>
+       
+       <Call name="addBean">
+               <Arg>
+                       <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
+                               <Set name="contexts">
+                                       <Ref refid="Contexts" />
+                               </Set>
+                               <Call id="extAppHotDeployProvider" name="addAppProvider">
+                                       <Arg>
+                                               <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
+                                                       <Set name="monitoredDirName"><SystemProperty name="AJSC_HOME" />/extApps</Set>
+                                                       <Set name="scanInterval">10</Set>
+                                                       <Set name="extractWars">true</Set>
+                                               </New>
+                                       </Arg>
+                               </Call>
+                       </New>
+               </Arg>
+       </Call>
+       
+       <Call name="addConnector">
+               <Arg>
+                       <New class="org.eclipse.jetty.server.ServerConnector">
+                               <Arg name="server">
+                                       <Ref refid="ajsc-server" />
+                               </Arg>
+                               <Set name="port"><SystemProperty name="AJSC_HTTP_PORT" default="8083" /></Set>
+                       </New>
+               </Arg>
+       </Call>
+
+       <Call id="sslConnector" name="addConnector">
+               <Arg>
+                       <New class="org.eclipse.jetty.server.ServerConnector">
+                               <Arg name="server">
+                                       <Ref refid="ajsc-server" />
+                               </Arg>
+                               <Arg name="factories">
+                                       <Array type="org.eclipse.jetty.server.ConnectionFactory">
+                                               <Item>
+                                                       <New class="org.eclipse.jetty.server.SslConnectionFactory">
+                                                               <Arg name="next">http/1.1</Arg>
+                                                               <Arg name="sslContextFactory">
+                                                                       <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
+                                                                               <Set name="KeyStorePath">file:<SystemProperty name="AJSC_HOME" />/bundleconfig/etc/auth/aai_keystore</Set>
+                                                                               <Set name="KeyStorePassword">
+                                                                                        <Call class="org.eclipse.jetty.util.security.Password" name="deobfuscate">
+                                                                               <Arg><SystemProperty name="KEY_STORE_PASSWORD" /></Arg>
+                                                                         </Call>
+                                                                               </Set>
+                                                                               <Set name="KeyManagerPassword">
+                                                                                        <Call class="org.eclipse.jetty.util.security.Password" name="deobfuscate">
+                                                                               <Arg><SystemProperty name="KEY_MANAGER_PASSWORD" /></Arg>
+                                                                         </Call>
+                                                                               </Set>
+                                                                               <Set name="needClientAuth">false</Set>
+                                                                       </New>
+                                                               </Arg>
+                                                       </New>
+                                               </Item>
+                                               <Item>
+                                                       <New class="org.eclipse.jetty.server.HttpConnectionFactory">
+                                                               <Arg name="config">
+                                                                       <New class="org.eclipse.jetty.server.HttpConfiguration">
+                                                                               <Call name="addCustomizer">
+                                                                                       <Arg>
+                                                                                               <New class="org.eclipse.jetty.server.SecureRequestCustomizer" />
+                                                                                       </Arg>
+                                                                               </Call>
+                                                                       </New>
+                                                               </Arg>
+                                                       </New>
+                                               </Item>
+                                       </Array>
+                               </Arg>
+                               <Set name="port"><SystemProperty name="AJSC_HTTPS_PORT" default="8446" /></Set>
+                               <Set name="idleTimeout">30000</Set>
+                       </New>
+               </Arg>
+       </Call>
+
+       <Get name="ThreadPool">
+               <Set name="minThreads"><SystemProperty name="AJSC_JETTY_ThreadCount_MIN" /></Set>
+               <Set name="maxThreads"><SystemProperty name="AJSC_JETTY_ThreadCount_MAX" /></Set>
+               <Set name="idleTimeout"><SystemProperty name="AJSC_JETTY_IDLETIME_MAX" /></Set>
+               <Set name="detailedDump">false</Set>
+       </Get>
+       <Call name="addBean">
+               <Arg>
+                       <New class="org.eclipse.jetty.security.HashLoginService">
+                               <Set name="name">Test Realm</Set>
+                               <Set name="config"><SystemProperty name="AJSC_HOME" />/etc/realm.properties</Set>
+                               <Set name="refreshInterval">5</Set>
+                               <Call name="start"></Call>
+                       </New>
+               </Arg>
+       </Call>
+</Configure>
diff --git a/aai-traversal/src/main/config/ajsc-jolokia-override-web.xml b/aai-traversal/src/main/config/ajsc-jolokia-override-web.xml
new file mode 100644 (file)
index 0000000..b242129
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+       metadata-complete="false" version="3.0">
+       
+       <filter-mapping>
+               <filter-name>InterceptorFilter</filter-name>
+               <url-pattern>/services/*</url-pattern>
+       </filter-mapping> 
+       <filter-mapping>
+               <filter-name>InterceptorFilter</filter-name>
+               <url-pattern>/rest/*</url-pattern>
+       </filter-mapping>  
+
+       <filter-mapping>
+               <filter-name>springSecurityFilterChain</filter-name>
+               <url-pattern>/*</url-pattern>
+       </filter-mapping>
+               
+       <servlet-mapping>
+               <servlet-name>ManagementServlet</servlet-name>
+               <url-pattern>/mgmt</url-pattern>
+       </servlet-mapping>
+        
+        <servlet-mapping>
+                       <servlet-name>RestletServlet</servlet-name>
+                       <url-pattern>/rest/*</url-pattern>
+       </servlet-mapping>
+
+       <servlet-mapping>
+               <servlet-name>CamelServlet</servlet-name>
+               <url-pattern>/services/*</url-pattern>
+       </servlet-mapping>
+       
+       <servlet>
+      <servlet-name>jolokia-agent</servlet-name>
+      <servlet-class>org.jolokia.http.AgentServlet</servlet-class>
+      <load-on-startup>2</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+      <servlet-name>jolokia-agent</servlet-name>
+      <url-pattern>/jolokia/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
\ No newline at end of file
diff --git a/aai-traversal/src/main/config/ajsc-override-web.xml b/aai-traversal/src/main/config/ajsc-override-web.xml
new file mode 100644 (file)
index 0000000..61e2836
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+       metadata-complete="false" version="3.0">
+
+       <filter-mapping>
+        <filter-name>WriteableRequestFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+       <filter-mapping>
+               <filter-name>InterceptorFilter</filter-name>
+               <url-pattern>/*</url-pattern>
+       </filter-mapping> 
+       <filter-mapping>
+               <filter-name>InterceptorFilter</filter-name>
+               <url-pattern>/rest/*</url-pattern>
+       </filter-mapping>  
+
+       <filter-mapping>
+               <filter-name>springSecurityFilterChain</filter-name>
+               <url-pattern>/*</url-pattern>
+       </filter-mapping>
+               
+       <servlet-mapping>
+               <servlet-name>ManagementServlet</servlet-name>
+               <url-pattern>/mgmt</url-pattern>
+       </servlet-mapping>
+        
+        <servlet-mapping>
+                       <servlet-name>RestletServlet</servlet-name>
+                       <url-pattern>/rest/*</url-pattern>
+       </servlet-mapping>
+
+       <servlet-mapping>
+               <servlet-name>CamelServlet</servlet-name>
+               <url-pattern>/*</url-pattern>
+       </servlet-mapping>
+       
+       
+
+</web-app>
\ No newline at end of file
diff --git a/aai-traversal/src/main/config/ajsc-request.xml b/aai-traversal/src/main/config/ajsc-request.xml
new file mode 100644 (file)
index 0000000..5d09b7a
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ns1:ErrorTranslationRequest
+       xsi:schemaLocation="http://csi.cingular.com/CSI/Namespaces/Types/Private/ErrorTranslationRequest.xsd ErrorTranslationRequest.xsd"
+       xmlns:ns1="http://csi.cingular.com/CSI/Namespaces/Types/Private/ErrorTranslationRequest.xsd"
+       xmlns:th="http://csi.cingular.com/CSI/Namespaces/Types/Private/Implementation/TransactionHeader.xsd"
+       xmlns:err="http://csi.cingular.com/CSI/Namespaces/Types/Public/ErrorResponse.xsd"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+       <ns1:TransactionHeader>
+               <th:applicationId></th:applicationId>
+               <th:MessageQualifier>
+                       <th:messageQualifier></th:messageQualifier>
+               </th:MessageQualifier>
+               <th:activityCode></th:activityCode>
+               <th:sequenceNumber></th:sequenceNumber>
+               <th:extendedSequenceNumber></th:extendedSequenceNumber>
+               <th:creationDate></th:creationDate>
+               <th:transactionDate></th:transactionDate>
+               <th:timeToLive></th:timeToLive>
+               <th:reasonCode></th:reasonCode>
+               <th:systemId></th:systemId>
+               <th:operatorId></th:operatorId>
+               <th:reference></th:reference>
+               <th:replyToAddress></th:replyToAddress>
+               <th:originatorId></th:originatorId>
+               <th:atlasMessageId></th:atlasMessageId>
+       </ns1:TransactionHeader>
+       <ns1:operation></ns1:operation>
+       <ns1:ServiceEntityFault>
+               <err:reportingServiceEntity></err:reportingServiceEntity>
+               <err:faultDate></err:faultDate>
+               <err:faultSequenceNumber></err:faultSequenceNumber>
+               <err:faultLevel></err:faultLevel>
+               <err:faultCode></err:faultCode>
+               <err:faultDescription></err:faultDescription>
+               <err:ServiceProviderRawError>
+                       <err:code></err:code>
+                       <err:description></err:description>
+                       <err:BISError>
+                               <err:code></err:code>
+                               <err:description></err:description>
+                               <err:origination></err:origination>
+                               <err:severity></err:severity>
+                       </err:BISError>
+               </err:ServiceProviderRawError>
+       </ns1:ServiceEntityFault>
+       <ns1:conversationID></ns1:conversationID>
+       <ns1:partnerName></ns1:partnerName>
+       <ns1:isRESTService></ns1:isRESTService>
+</ns1:ErrorTranslationRequest>
\ No newline at end of file
diff --git a/aai-traversal/src/main/config/caet.properties b/aai-traversal/src/main/config/caet.properties
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/aai-traversal/src/main/config/hazelcast-client.properties b/aai-traversal/src/main/config/hazelcast-client.properties
new file mode 100644 (file)
index 0000000..2624d3f
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2008-2013, Hazelcast, Inc. 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.
+#
+
+hazelcast.client.group.name                 = ajsc
+hazelcast.client.group.pass                 = ajscpass
+hazelcast.client.connection.timeout         = 30000
+hazelcast.client.connection.attempts.limit  = 3
+hazelcast.client.reconnection.timeout       = 5000
+hazelcast.client.reconnection.attempts.limit= 5
+hazelcast.client.shuffle.addresses          = false
+hazelcast.client.update.automatic           = true
+hazelcast.client.addresses                  = localhost, 127.0.0.1
\ No newline at end of file
diff --git a/aai-traversal/src/main/config/jul-redirect.properties b/aai-traversal/src/main/config/jul-redirect.properties
new file mode 100644 (file)
index 0000000..8b6624d
--- /dev/null
@@ -0,0 +1,13 @@
+
+#      Bridge JUL->slf4j Logging Configuration File
+#
+# This file bridges the JUL logging infrastructure into
+# SLF4J so JUL logs go to logback implementation provided
+# in this project.  SLF4J also captures log4j and has 
+# other framework options as well providing a common
+# logging infrastructure for capturing all logs from different
+# libraries using different frameworks in one place.
+
+#      Global properties
+handlers=org.slf4j.bridge.SLF4JBridgeHandler
+.level= ALL
diff --git a/aai-traversal/src/main/config/keyfile b/aai-traversal/src/main/config/keyfile
new file mode 100644 (file)
index 0000000..6a1657e
--- /dev/null
@@ -0,0 +1,27 @@
+ctRt8XTd7N57kcm0npZOWSDF5I69w9K97cQS_ep0AgxgHmYB0WtYblsrMGuHfyS1o4697zLiIeoS
+Nn5kE1kedl4c4HevfuwfoJpWyiugYusNOqbTGQJ1MHOwqiBEJnjXepZEoz1btaW_hDO7uz-BoD4t
+SxwNRwVQpcg0_CmBX-yIW2YCIECoxZH9_X_8fcXYHP2VgFxxBpvjgycNQlyN15_VSuLwn3Wj0W8_
+8chRxGURyhp8iEBSb4tIdN5jXkhCma7AP7wreMufFQqXjdfWqIisJPfIpS3znl5IiTOZP22XhHay
+gq2KFwABVqjM71m5czEz1ojGkbFEAGImrY-VFHuug2u4ss4VW7TGeJst0z7I5vrn5M6i9Eb6xiGh
+jNUebRCV3cYGrtD9SlvjJBVVeP_3OrkxlD4oktx-JTRJzYtXADB5if2gtpYxy84kqrz7ltr5rXUH
+zSG7ujKCXOOE_Wk6vQPSjYPnum6R_mxOorCNCvtf6ne85Xd81DZlJM-CleVNdOU7g1xie-gBZPAX
+bOvWf6p_pVNmH76v-m4XLAAUqEzt-9PvNmirODiDiY5bNz6l-1ejw8IyQYb37e_3sN_LjF7A9HgB
+Dia7kNjsfB7_2vB7R4qjwNLsmTMnQCDANnNpl9VpotZ4blPhhOWhB1Tg3lxc-z-VRV7GBbl_2eQd
+3eYUT1Z5Li184W4-pft_TCaDJ1NyaJd1CQxQEuIORdq5B6Q2L9SMmmOOh82Czu5_Ro80IGikHXHp
+Lqf2fIaceY_IBAeGp2iPjtXdkghV24vIT49oRfqf6sBKAPy-88xILnMWM6M5bMCETKn7UvM1kV5y
+ZQYlsi-36n73ETZyiFs1PLqe8D6dRURrcBG_B9i1MafNiWa-elG6E0X0pSK9CadchSA0KRMaKtfE
+6-iyUqE-bx-0ELTbV2y7gLdu5MVtjRmQB5ozoaBq8ik4-jAWAsKpTv4DfWoMp9DkRENlKeauayuT
+j_VAGhqy07pIntQKtbK9EP0tndSKtF3WLwHel1I5C3lthhkxxfzpxURBxO1ZJMFJZ6rLu1Ku03zw
+LJ7nFFR_YfJ7tnGZE4PEt7MOZNiNoD3__9PthO5HmZdk1gPMrKlojU1hyR3IlbVShUst6rA3MkWk
+MD-zlw9mhNgaV3xvPJ945pYPe4C6qIwxXoiXGHyhv_0MpcvuMW-pUuAZXfkuiqNwQnpUTLBD0YJw
+uwMbE7sN40e6-BSxEiMOab7s2gShbaK9JjCMQUH_vAuQSZjU4sn53jsS7U4DHntzgxVYttIwGZaU
+b-1R7jYphNJnCI8rPB_xjJ0OMssNKT7lYRgG_ZuKvifYvJWt-NwD0z2qoePcRGExXuioRDNR4SlB
+-RN33dYhp6vRsHKT1oLpl-UJB6dqJlZ2dCsfc7vT1Vs0SYidRYXCUJNBSePI4-1LMlHKOqGASBcg
+pl589601-EtO7ch3RoaL26rNXzA-umUWYRPQPZ76wcgK2j4k5Ndub5dWK9jI6UW3RbF6ixe0Yw2j
+_Pipt4EX8R6-sb87D69JOOnZlFVB6EcCO07Q7j6DavpUNHlLmDmPgArqODh002scvW1ryMxBR2XE
+m3kGQh2IFh5Qru8duxblEYE-lmHGxXVgDtKiKgHwPTkaxcquEtZTEJxaIJIgoKj7SgMzdfbeLlJM
+RwbdvExmnRT9ivFImeIV7ACPnfBP3URd82kTG8FyiMvSpdCLL16FWOd9gjZuMstqZrmIVF8tO2WT
+COMIx-jqvQD2zS1Ul5p0szJaf-CxBjy7-cJIaAyEToR1T5bBFtQt4sEFxG7XG0cCoXShqclL70TV
+W13X5pY55YwHkCR4mRjc0o0ZKStY3OADVLFom1bC9AmMBqU4PsKNAX29LT37WE-I23tQgzid0Ix9
+JuVzlbOTvi19uLYbltrHavU3UbVhYxNNI7Y7tM02xfq3LhGqZG5EPS-WAB9bBixHQqw78cd9iqIr
+hHlZW80l1kgs1ezMqgxfwDuiFOZIu9UWQ6vSnTAvfhwJhcr77gSk5Gu957uxzleaS4gVwTYU
diff --git a/aai-traversal/src/main/config/realm.properties b/aai-traversal/src/main/config/realm.properties
new file mode 100644 (file)
index 0000000..88d9e56
--- /dev/null
@@ -0,0 +1,11 @@
+# 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
diff --git a/aai-traversal/src/main/config/runner-web.xml b/aai-traversal/src/main/config/runner-web.xml
new file mode 100644 (file)
index 0000000..44ba656
--- /dev/null
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+       metadata-complete="false" version="3.0">
+
+       <context-param>
+               <param-name>contextConfigLocation</param-name>
+               <param-value>/WEB-INF/spring-servlet.xml,
+                                       classpath:applicationContext.xml
+               </param-value>
+       </context-param>
+       
+       <context-param>
+        <param-name>spring.profiles.default</param-name>
+        <param-value>nooauth</param-value>
+    </context-param>
+    
+       <listener>
+               <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+       </listener>
+       
+       <servlet>
+               <servlet-name>ManagementServlet</servlet-name>
+               <servlet-class>ajsc.ManagementServlet</servlet-class>
+       </servlet>
+
+       <filter>
+        <filter-name>WriteableRequestFilter</filter-name>
+        <filter-class>com.att.ajsc.csi.writeablerequestfilter.WriteableRequestFilter</filter-class>
+    </filter>
+    
+       <filter> 
+               <filter-name>InterceptorFilter</filter-name>
+               <filter-class>ajsc.filters.InterceptorFilter</filter-class>
+               <init-param>
+                <param-name>preProcessor_interceptor_config_file</param-name>
+                <param-value>/etc/PreProcessorInterceptors.properties</param-value>
+        </init-param>
+        <init-param>
+                <param-name>postProcessor_interceptor_config_file</param-name>
+                <param-value>/etc/PostProcessorInterceptors.properties</param-value>
+        </init-param>
+        
+       </filter>
+
+        <servlet>
+               <servlet-name>RestletServlet</servlet-name>
+               <servlet-class>ajsc.restlet.RestletSpringServlet</servlet-class>
+               <init-param>
+                               <param-name>org.restlet.component</param-name>
+                               <param-value>restletComponent</param-value>
+               </init-param>
+       </servlet>
+       
+       <servlet>
+               <servlet-name>CamelServlet</servlet-name>
+               <servlet-class>ajsc.servlet.AjscCamelServlet</servlet-class>
+       </servlet>
+
+
+       <filter>
+               <filter-name>springSecurityFilterChain</filter-name>
+               <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+       </filter>
+
+       <servlet>
+               <servlet-name>spring</servlet-name>
+               <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+               <load-on-startup>1</load-on-startup>
+       </servlet>      
+       
+       
+       
+       <servlet-mapping>
+               <servlet-name>spring</servlet-name>
+               <url-pattern>/</url-pattern>
+       </servlet-mapping>
+       
+       <listener>
+               <listener-class>
+             org.openecomp.aai.util.AAIAppServletContextListener
+        </listener-class>
+   </listener>
+    <listener>
+               <listener-class>
+             org.openecomp.aai.ingestModel.IngestModelListener
+        </listener-class>
+   </listener>
+       <security-constraint>
+               <web-resource-collection>
+                       <web-resource-name>Open Source</web-resource-name>
+                       <url-pattern>/aai/*</url-pattern>
+               </web-resource-collection>
+               <auth-constraint>
+                       <role-name>admin</role-name>
+               </auth-constraint>
+               <user-data-constraint>
+                       <transport-guarantee>CONFIDENTIAL</transport-guarantee>
+               </user-data-constraint>
+       </security-constraint>
+
+       <login-config>
+               <auth-method>BASIC</auth-method>
+               <realm-name>Test Realm</realm-name>
+       </login-config>
+
+       <security-role>
+               <role-name>admin</role-name>
+       </security-role>
+
+</web-app>
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/JaxrsErrorMessageLookupService.java b/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/JaxrsErrorMessageLookupService.java
new file mode 100644 (file)
index 0000000..ca78bac
--- /dev/null
@@ -0,0 +1,98 @@
+/*-
+ * ============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.ajsc_aai;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.context.ContextLoader;
+import org.springframework.web.context.WebApplicationContext;
+
+import ajsc.ErrorMessageLookupService;
+
+@Path("/errormessage")
+public class JaxrsErrorMessageLookupService {
+
+       private final static Logger logger = LoggerFactory
+                       .getLogger(ErrorMessageLookupService.class);
+
+       /**
+        * Gets the message.
+        *
+        * @param input the input
+        * @param errorCode the error code
+        * @param appId the app id
+        * @param operation the operation
+        * @param messageText the message text
+        * @param isRESTService the is REST service
+        * @param faultEntity the fault entity
+        * @param ConvID the conv ID
+        * @return the message
+        */
+       @GET
+       @Path("/emls")
+       @Produces("text/plain")
+       public String getMessage(@PathParam("input") String input,
+                       @HeaderParam("errorCode") String errorCode,
+                       @HeaderParam("appId") String appId,
+                       @HeaderParam("operation") String operation,
+                       @HeaderParam("messageText") String messageText,
+                       @HeaderParam("isRESTService") String isRESTService,
+                       @HeaderParam("faultEntity") String faultEntity,
+                       @HeaderParam("ConvID") String ConvID) {
+
+               Map<String, String> headers = new HashMap<String, String>();
+               headers.put(errorCode, errorCode);
+               headers.put(appId, appId);
+               headers.put(operation, operation);
+               headers.put(messageText, messageText);
+               headers.put(isRESTService, isRESTService);
+               headers.put(faultEntity, faultEntity);
+               headers.put(ConvID, ConvID);
+               
+               WebApplicationContext applicationContext = ContextLoader
+                               .getCurrentWebApplicationContext();
+
+               ErrorMessageLookupService e = (ErrorMessageLookupService) applicationContext
+                               .getBean("errorMessageLookupService");
+
+               String message = e.getExceptionDetails(appId, operation, errorCode,
+                               messageText,isRESTService, faultEntity, ConvID);
+
+               System.out.println("Error code = " + errorCode);
+               System.out.println("appId = " + appId);
+               System.out.println("operation = " + operation);
+               System.out.println("messageText = " + messageText);
+               System.out.println("isRESTService = " + isRESTService);
+               System.out.println("faultEntity = " + faultEntity);
+               System.out.println("ConvID = " + ConvID);
+               return "The exception message is:\n " + message;
+       }
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/JaxrsUserService.java b/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/JaxrsUserService.java
new file mode 100644 (file)
index 0000000..39c78f6
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ * ============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.ajsc_aai;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import java.util.Map;
+import java.util.HashMap;
+
+@Path("/user")
+public class JaxrsUserService {
+       
+       private static final Map<String,String> userIdToNameMap;
+       static {
+               userIdToNameMap = new HashMap<String,String>();
+               userIdToNameMap.put("userID1","Name1");
+               userIdToNameMap.put("userID2","Name2");
+       }
+       
+    /**
+     * Lookup user.
+     *
+     * @param userId the user id
+     * @return the string
+     */
+    @GET
+    @Path("/{userId}")
+    @Produces("text/plain")
+    public String lookupUser(@PathParam("userId") String userId) {
+       String name = userIdToNameMap.get(userId);
+        return name != null ? name : "unknown id";
+    }
+    
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/filemonitor/ServicePropertiesListener.java b/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/filemonitor/ServicePropertiesListener.java
new file mode 100644 (file)
index 0000000..22c1cb9
--- /dev/null
@@ -0,0 +1,19 @@
+/*-
+ * ============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=========================================================
+ */
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/filemonitor/ServicePropertiesMap.java b/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/filemonitor/ServicePropertiesMap.java
new file mode 100644 (file)
index 0000000..656b290
--- /dev/null
@@ -0,0 +1,126 @@
+/*-
+ * ============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.ajsc_aai.filemonitor;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class ServicePropertiesMap 
+{
+       private static HashMap<String, HashMap<String, String>> mapOfMaps = new HashMap<String, HashMap<String, String>>();
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ServicePropertiesMap.class);
+       
+       /**
+        * Refresh.
+        *
+        * @param file the file
+        * @throws Exception the exception
+        */
+       public static void refresh(File file) throws Exception
+       {
+               try
+               {
+                       LOGGER.info("Loading properties - " + (file != null?file.getName():""));
+                       
+                       //Store .json & .properties files into map of maps
+                       String filePath = file.getPath();
+                       
+                       if(filePath.lastIndexOf(".json")>0){
+                               
+                               ObjectMapper om = new ObjectMapper();
+                               TypeReference<HashMap<String, String>> typeRef = new TypeReference<HashMap<String, String>>() {};
+                               HashMap<String, String> propMap = om.readValue(file, typeRef);
+                               HashMap<String, String> lcasePropMap = new HashMap<String, String>();
+                               for (String key : propMap.keySet() )
+                               {
+                                       String lcaseKey = ifNullThenEmpty(key);
+                                       lcasePropMap.put(lcaseKey, propMap.get(key));
+                               }
+                               
+                               mapOfMaps.put(file.getName(), lcasePropMap);
+                               
+                               
+                       }else if(filePath.lastIndexOf(".properties")>0){
+                               Properties prop = new Properties();
+                               FileInputStream fis = new FileInputStream(file);
+                               prop.load(fis);
+                               
+                               @SuppressWarnings("unchecked")
+                               HashMap<String, String> propMap = new HashMap<String, String>((Map)prop);
+                               
+                               mapOfMaps.put(file.getName(), propMap);
+                       }
+
+                       LOGGER.info("File - " + file.getName() + " is loaded into the map and the corresponding system properties have been refreshed");
+               }
+               catch (Exception e)
+               {
+                       LOGGER.error("File " + (file != null?file.getName():"") + " cannot be loaded into the map ", e);
+                       throw new Exception("Error reading map file " + (file != null?file.getName():""), e);
+               }
+       }
+       
+       /**
+        * Gets the property.
+        *
+        * @param fileName the file name
+        * @param propertyKey the property key
+        * @return the property
+        */
+       public static String getProperty(String fileName, String propertyKey)
+       {
+               HashMap<String, String> propMap = mapOfMaps.get(fileName);
+               return propMap!=null?propMap.get(ifNullThenEmpty(propertyKey)):"";
+       }
+       
+       /**
+        * Gets the properties.
+        *
+        * @param fileName the file name
+        * @return the properties
+        */
+       public static HashMap<String, String> getProperties(String fileName){
+               return mapOfMaps.get(fileName);
+       }
+       
+       /**
+        * If null then empty.
+        *
+        * @param key the key
+        * @return the string
+        */
+       private static String ifNullThenEmpty(String key) {
+               if (key == null) {
+                       return "";
+               } else {                                        
+                       return key;
+               }               
+       }
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/filemonitor/ServicePropertyService.java b/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/filemonitor/ServicePropertyService.java
new file mode 100644 (file)
index 0000000..22c1cb9
--- /dev/null
@@ -0,0 +1,19 @@
+/*-
+ * ============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=========================================================
+ */
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/util/ServicePropertiesMapBean.java b/aai-traversal/src/main/java/org/openecomp/aai/ajsc_aai/util/ServicePropertiesMapBean.java
new file mode 100644 (file)
index 0000000..7577de7
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============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.ajsc_aai.util;
+
+import org.openecomp.aai.ajsc_aai.filemonitor.ServicePropertiesMap;
+
+public class ServicePropertiesMapBean {
+
+       /**
+        * Gets the property.
+        *
+        * @param propFileName the prop file name
+        * @param propertyKey the property key
+        * @return the property
+        */
+       public static String getProperty(String propFileName, String propertyKey) {
+               return ServicePropertiesMap.getProperty(propFileName, propertyKey);
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/db/DbMethHelper.java b/aai-traversal/src/main/java/org/openecomp/aai/db/DbMethHelper.java
new file mode 100644 (file)
index 0000000..79172d9
--- /dev/null
@@ -0,0 +1,158 @@
+/*-
+ * ============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.db;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.openecomp.aai.parsers.query.QueryParser;
+import org.openecomp.aai.parsers.relationship.RelationshipToURI;
+import org.openecomp.aai.query.builder.QueryBuilder;
+import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
+
+public class DbMethHelper {
+
+       private final Loader loader;
+       private final TransactionalGraphEngine engine;
+       
+       protected DbMethHelper() {
+               this.loader = null;
+               this.engine = null;
+       }
+       public DbMethHelper(Loader loader, TransactionalGraphEngine engine) {
+               this.loader = loader;
+               this.engine = engine;
+       }
+       /**
+        * 
+        * @param type
+        * @param map - form [{type}.{propname}:{value}]
+        * @return
+        * @throws UnsupportedEncodingException
+        * @throws AAIException
+        */
+       public Optional<Vertex> searchVertexByIdentityMap(String type, Map<String, Object> map) throws AAIException {
+               
+               Introspector relationship = constructRelationship(type, map);
+               RelationshipToURI parser;
+               URI uri;
+               QueryParser queryParser;
+               try {
+                       parser = new RelationshipToURI(loader, relationship);
+                       uri = parser.getUri();
+                       queryParser = this.engine.getQueryBuilder().createQueryFromURI(uri);
+               } catch (UnsupportedEncodingException e) {
+                       throw new AAIException("AAI_3000");
+               }
+               
+               List<Vertex> results = queryParser.getQueryBuilder().toList();
+               
+               return reduceToSingleVertex(results, map);
+       }
+       
+       /**
+        * @param type
+        * @param map - form [{propname}:{value}]
+        * @return
+        * @throws AAIException
+        */
+       public Optional<Vertex> locateUniqueVertex(String type, Map<String, Object> map) throws AAIException {
+       
+               return reduceToSingleVertex(locateUniqueVertices(type, map), map);
+       }
+       
+       public List<Vertex> locateUniqueVertices(String type, Map<String, Object> map) throws AAIException {
+               Introspector obj = this.createIntrospectorFromMap(type, map);
+               QueryBuilder builder = this.engine.getQueryBuilder().exactMatchQuery(obj);
+               
+               return builder.toList();
+       }
+       private Introspector constructRelationship(String type, Map<String, Object> map) throws AAIUnknownObjectException {
+               final Introspector relationship = loader.introspectorFromName("relationship");
+               relationship.setValue("related-to", type);
+               final List<Object> data = relationship.getValue("relationship-data");
+               for (Entry<String, Object> entry : map.entrySet()) {
+                       final Introspector dataObj = loader.introspectorFromName("relationship-data");
+                       dataObj.setValue("relationship-key", entry.getKey());
+                       dataObj.setValue("relationship-value", entry.getValue());
+                       data.add(dataObj.getUnderlyingObject());
+               }
+               
+               return relationship;
+       }
+       
+       private Introspector createIntrospectorFromMap(String targetNodeType, Map<String, Object> propHash) throws AAIUnknownObjectException {
+               final Introspector result = loader.introspectorFromName(targetNodeType);
+               for (Entry<String, Object> entry : propHash.entrySet()) {
+                       result.setValue(entry.getKey(), entry.getValue());
+               }
+               return result;
+       }
+       
+       private Optional<Vertex> reduceToSingleVertex(List<Vertex> vertices, Map<String, Object> map) throws AAIException {
+               if (vertices.isEmpty()){
+                       return Optional.empty();
+               } else if (vertices.size() > 1) {
+                       throw new AAIException("AAI_6112", "More than one Node found by getUniqueNode for params: " + map);
+               }
+               
+               return Optional.of(vertices.get(0));
+       }
+       public List<String> getVertexProperties(Vertex v) {
+               List<String> retArr = new ArrayList<>();
+               if( v == null ){
+                       retArr.add("null Node object passed to showPropertiesForNode()\n");
+               }
+               else {
+                       String nodeType;
+                       Object ob = v.<Object>property("aai-node-type").orElse(null);
+                       if( ob == null ){
+                               nodeType = "null";
+                       }
+                       else{
+                               nodeType = ob.toString();
+                       }
+                       
+                       retArr.add(" AAINodeType/VtxID for this Node = [" + nodeType + "/" + v.id() + "]");
+                       retArr.add(" Property Detail: ");
+                       Iterator<VertexProperty<Object>> pI = v.properties();
+                       while( pI.hasNext() ){
+                               VertexProperty<Object> tp = pI.next();
+                               Object val = tp.value();
+                               retArr.add("Prop: [" + tp.key() + "], val = [" + val + "] ");
+                       }
+               }
+               return retArr;
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/DbEdgeGroup.java b/aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/DbEdgeGroup.java
new file mode 100644 (file)
index 0000000..56a9a4b
--- /dev/null
@@ -0,0 +1,439 @@
+/*-
+ * ============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.dbgraphgen;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections.map.MultiValueMap;
+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.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+import org.openecomp.aai.dbgen.DbMeth;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.exceptions.AAIExceptionWithInfo;
+import org.openecomp.aai.ingestModel.DbMaps;
+import org.openecomp.aai.ingestModel.IngestModelMoxyOxm;
+import org.openecomp.aai.serialization.db.EdgeRule;
+import org.openecomp.aai.serialization.db.EdgeRules;
+import org.openecomp.aai.serialization.db.EdgeType;
+import org.openecomp.aai.serialization.db.MultiplicityRule;
+import org.openecomp.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.thinkaurelius.titan.core.TitanEdge;
+import com.thinkaurelius.titan.core.TitanTransaction;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+public class DbEdgeGroup {
+       
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DbEdgeGroup.class);
+       
+       /**
+        * Replace edge group.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param startVert the start vert
+        * @param scope the scope
+        * @param relatedNodesMultiMap the related nodes multi map
+        * @param apiVersion the api version
+        * @throws AAIException the AAI exception
+        */
+       public static void replaceEdgeGroup( String transId, 
+                                                                               String fromAppId, 
+                                                                               TitanTransaction graph,  
+                                                                               TitanVertex startVert, 
+                                                                               String scope, 
+                                                                               MultiValueMap relatedNodesMultiMap, // supports multiple entries for same nodetype
+                                                                               String apiVersion ) throws AAIException{
+
+       // --------------------------------------------------------------------
+       // NOTE --- This routine is only used for "cousin" relationships. 
+       // --------------------------------------------------------------------
+
+       /*
+        *  scope can be one of these:  
+        *    a) "ALL_COUSIN_REL"  
+        *    b) "ONLY_PASSED_COUSINS_REL" (only look at the edge types that are
+        *                                 represented in the passed list of relationships)
+        *        
+        *   Given a startNode and a list of relationshipInfo, we need to check the database and then, 
+        *   1) Delete any in-scope db relationships which are not represented in the relationshipList.
+        *      So, for ALL_COUSIN_REL, we would delete any db relationship that had an edge with
+        *         parentOf = false if it was not represented in the passed Relationship List.
+        *      For ONLY_PASSED_COUSINS_REL - we'd do the same as above, but only for edges that match the 
+        *         type in the passed relationshipList.  We'd leave any others alone.
+        *   2) Then, Persist (add/update) all the remaining passed-in relationships.        
+        */
+
+       if( !scope.equals("ALL_COUSIN_REL") && !scope.equals("ONLY_PASSED_COUSINS_REL")  ){
+               throw new AAIException("AAI_6120", "Illegal scope parameter passed: [" + scope + "]."); 
+       }
+
+       HashMap <String,String> vidToNodeTypeInDbHash = new HashMap <String,String>();
+       HashMap <String,String> nodeTypeInReqHash = new HashMap <String,String>();
+       HashMap <String,TitanEdge> vidToEdgeInDbHash = new HashMap <String,TitanEdge>();
+       HashMap <String,TitanVertex> vidToTargetVertexHash = new HashMap <String,TitanVertex>();
+
+       //------------------------------------------------------------------------------------------------------------
+       // 1) First -- look what is currently in the db -- 
+       //        "cousins" => grab all nodes connected to startVertex that have edges with param: isParent = false.
+       //------------------------------------------------------------------------------------------------------------
+       GraphTraversalSource conPipeTraversal = startVert.graph().traversal();
+       GraphTraversal<Vertex, Edge> conPipe = conPipeTraversal.V(startVert).bothE().has("isParent",false);
+       // Note - it's ok if nothing is found
+       if( conPipe != null ){
+               while( conPipe.hasNext() ){
+                       TitanEdge ed = (TitanEdge) conPipe.next();
+                       TitanVertex cousinV = ed.otherVertex(startVert);
+                       String vid = cousinV.id().toString();
+                       String noTy = cousinV.<String>property("aai-node-type").orElse(null);
+                       vidToNodeTypeInDbHash.put(vid, noTy);
+                       vidToEdgeInDbHash.put(vid, ed);
+
+                       LOGGER.info("Found connected cousin vid(s) in db: [" + cousinV.id().toString() + "]");
+               }
+       }
+
+       //------------------------------------------------------------------------------------------------------------
+       //2) Get a List of the Titan nodes that the end-state list wants to be connected to             
+       //------------------------------------------------------------------------------------------------------------
+       ArrayList <TitanVertex> targetConnectedToVertList = new ArrayList<TitanVertex>();               
+       if( relatedNodesMultiMap != null ) {
+               
+        Set entrySet = relatedNodesMultiMap.entrySet();
+        Iterator it = entrySet.iterator();
+        //System.out.println("  Object key  Object value");
+        while (it.hasNext()) {
+            Map.Entry mapEntry = (Map.Entry) it.next();
+                       String rel2Nt = (String) mapEntry.getKey();
+                       int i = 0;
+                       ArrayList <HashMap<String, Object>> propList = ((ArrayList<HashMap<String, Object>>)relatedNodesMultiMap.get(rel2Nt));
+                       while (i < propList.size()) {
+                               HashMap<String, Object> propFilterHash = (HashMap<String, Object>) propList.get(i++);
+                               
+                               TitanVertex targetVert;
+                               
+                               try {
+                                       targetVert = DbMeth.getUniqueNodeWithDepParams( transId, 
+                                                                                                                                       fromAppId, 
+                                                                                                                                       graph, 
+                                                                                                                                       rel2Nt, 
+                                                                                                                                       propFilterHash, 
+                                                                                                                                       apiVersion );
+                               } catch (AAIException e) {
+                                       if (e.getErrorObject().getErrorCode().equals("6114"))
+                                               throw new AAIExceptionWithInfo("AAI_6129", 
+                                                                                                               e, 
+                                                                                                               "Node of type " + rel2Nt + " not found for properties:" + propFilterHash.toString(),
+                                                                                                               propFilterHash,
+                                                                                                               rel2Nt);
+                                       else 
+                                               throw e;
+                               }
+                       
+                               targetConnectedToVertList.add(targetVert);
+       
+                               String vid = targetVert.id().toString();
+                               String noTy = targetVert.<String>property("aai-node-type").orElse(null);
+                               nodeTypeInReqHash.put(noTy, "");
+                               vidToTargetVertexHash.put(vid, targetVert);
+       
+                               LOGGER.info("They request edges to these vids:[" + targetVert.id().toString() + "]");
+                       }
+        }
+       }
+
+       //-------------------------------------------------------------------------------------------------------------------
+       // 3) Compare what is in the DB with what they are requesting as an end-state. 
+       //    If any are found in the db-list but not the new-list, delete them from the db (conditionally - based on scope)
+       //-------------------------------------------------------------------------------------------------------------------
+       String startVtxNT = startVert.<String>property("aai-node-type").orElse(null);
+       for( Map.Entry<String, TitanEdge> entry : vidToEdgeInDbHash.entrySet() ){
+               String vertId = entry.getKey();
+               TitanEdge dbEd = entry.getValue();
+               if( ! vidToTargetVertexHash.containsKey(vertId) ){    
+                       if( scope.equals("ALL_COUSIN_REL") ){
+                               LOGGER.info("We will DELETE existing DB-edge to vids = [" + entry.getKey() + "]");
+                               DbMeth.removeAaiEdge(transId, fromAppId, graph, dbEd);
+                       }
+                       else if( scope.equals("ONLY_PASSED_COUSINS_REL") ){
+                               // If they use "ONLY_PASSED_COUSINS_REL" scope, they want us to delete an edge ONLY if:
+                               //      a) this edge is the same type that they passed in (but goes to a different endpoint)
+                               //  AND b) this additional edge would break the multiplicity edge rule.  
+                               String ntInDb = vidToNodeTypeInDbHash.get(vertId);
+                               if( nodeTypeInReqHash.containsKey(ntInDb) && additionalEdgeWouldBreakMultEdgeRule(startVtxNT, ntInDb) ){
+                                       LOGGER.info("We will DELETE existing DB-edge to vids = [" + entry.getKey() + "]");
+                                       DbMeth.removeAaiEdge(transId, fromAppId, graph, dbEd);
+                               }
+                       }
+               }
+       }
+
+       //---------------------------------------------------------------
+       // 4) add/update (persist) all the relations on the new-list
+       //---------------------------------------------------------------
+       for( Map.Entry<String, TitanVertex> entry : vidToTargetVertexHash.entrySet() ){
+               LOGGER.info("Call persistAaiEdge on edge(s) going to vids = " + "[" + entry.getKey() + "]");
+               TitanVertex targV = entry.getValue();
+               DbMeth.persistAaiEdge(transId, fromAppId, graph, startVert, targV, apiVersion, "cousin");
+       }
+
+       return;
+
+}// End replaceEdgeGroup()
+
+
+/**
+ * Additional edge would break mult edge rule.
+ *
+ * @param startNodeType the start node type
+ * @param endNodeType the end node type
+ * @return the boolean
+ * @throws AAIException the AAI exception
+ */
+private static Boolean additionalEdgeWouldBreakMultEdgeRule( String startNodeType, String endNodeType )
+       throws AAIException {
+       // Return true if a second edge from the startNodeType to the endNodeType would
+       // break a multiplicity edge rule.
+       // Ie.  Adding an edge to a second tenant (endNode) from a vserver (startNode) node would be flagged by this
+       //   if we have our multiplicity rule set up for the "vserver-tenant" edge set up as "Many2One" or if
+       //   it was set up the other way, "tenant-vserver" as "One2Many" or even if it was "One2One".  In any of 
+       //   those scenarios, the addition of an edge from a particular vserver to an additional tenant node
+       //   would break the rule.
+       
+       EdgeRule edgeRule = null;
+       boolean reversed = false;
+       
+       if (EdgeRules.getInstance().hasEdgeRule(startNodeType, endNodeType)) {
+       } else if (EdgeRules.getInstance().hasEdgeRule(endNodeType, startNodeType)) {
+               reversed = true;
+       }
+       
+       try {
+               edgeRule = EdgeRules.getInstance().getEdgeRule(EdgeType.COUSIN, startNodeType, endNodeType);
+       } catch (NoEdgeRuleFoundException e) {
+               return false;
+       }
+
+
+       if (edgeRule.getMultiplicityRule().equals(MultiplicityRule.ONE2ONE)) {
+               return true;
+       } else if (reversed && edgeRule.getMultiplicityRule().equals(MultiplicityRule.ONE2MANY)) {
+               return true;
+       } else if (!reversed && edgeRule.getMultiplicityRule().equals(MultiplicityRule.MANY2ONE)) {
+               return true;
+       } else {
+               return false;
+       }
+
+       
+}// end of additionalEdgeWouldBreakMultEdgeRule()
+
+/**
+ * Delete edge group.
+ *
+ * @param transId the trans id
+ * @param fromAppId the from app id
+ * @param graph the graph
+ * @param startVert the start vert
+ * @param relatedNodesMultiMap the related nodes multi map
+ * @param apiVersion the api version
+ * @return void
+ * @throws AAIException the AAI exception
+ */
+public static void deleteEdgeGroup( String transId, 
+                                                                       String fromAppId, 
+                                                                       TitanTransaction graph,  
+                                                                       TitanVertex startVert, 
+                                                                       MultiValueMap relatedNodesMultiMap, 
+                                                                       String apiVersion ) throws AAIException{
+       // --------------------------------------------------------------------
+       // NOTE - This routine is only used for "cousin" relationships. 
+       // ALSO - an edge deletion will fail if that edge was needed by
+       //        the node on one of the sides for uniqueness.  We're just 
+       //        being careful here - so far, I don't think a cousin-edge
+       //        is ever used for this kind of dependency.
+       // --------------------------------------------------------------------
+
+       HashMap <String,TitanEdge> cousinVidToEdgeInDbHash = new HashMap <String,TitanEdge>();
+       String startVertNT = startVert.<String>property("aai-node-type").orElse(null);
+       String startVertVid = startVert.id().toString();
+       DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(apiVersion);
+       Collection <String> startVertDepNTColl =  dbMaps.NodeDependencies.get(startVertNT);
+
+       //-----------------------------------------------------------------------------------------------------
+       // Get a list of vertexes that are attached to the startVert as "cousins" and the connecting edges
+       //-----------------------------------------------------------------------------------------------------
+       GraphTraversalSource conPipeTraversal = startVert.graph().traversal();
+       GraphTraversal<Vertex, Edge> conPipe = conPipeTraversal.V(startVert).bothE().has("isParent",false);
+       if( conPipe != null ){
+               while( conPipe.hasNext() ){
+                       TitanEdge ed = (TitanEdge) conPipe.next();
+                       TitanVertex cousinV = ed.otherVertex(startVert);
+                       String vid = cousinV.id().toString();
+                       cousinVidToEdgeInDbHash.put(vid, ed);
+               }
+       }
+
+       //-------------------------------------------------------------
+       //      Look through the Relationship info passed in.
+       //  Delete edges as requested if they check-out as cousins.
+       //-------------------------------------------------------------
+       Boolean isFirst = true;
+       String msg = "Deleting edges from vid = " + startVertVid + "(" + startVertNT + "), to these: [";
+       if( relatedNodesMultiMap != null ) {                    
+        Set entrySet = relatedNodesMultiMap.entrySet();
+        Iterator it = entrySet.iterator();
+        //System.out.println("  Object key  Object value");
+        while (it.hasNext()) {
+            Map.Entry mapEntry = (Map.Entry) it.next();
+                       String rel2Nt = (String) mapEntry.getKey();
+                       HashMap<String, Object> propFilterHash = (HashMap<String, Object>)((ArrayList) relatedNodesMultiMap.get(rel2Nt)).get(0);
+                       TitanVertex otherEndVert = DbMeth.getUniqueNodeWithDepParams( transId, fromAppId, graph, rel2Nt, propFilterHash, apiVersion ); 
+                       String otherNT = otherEndVert.<String>property("aai-node-type").orElse(null);
+                       String reqDelConnectedVid = otherEndVert.id().toString();
+                       if( !cousinVidToEdgeInDbHash.containsKey(reqDelConnectedVid) ){
+                               throw new AAIException("AAI_6127", "COUSIN Edge between " + startVertVid + " (" + startVertNT + ") and " + reqDelConnectedVid +
+                                               "(" + otherNT + ") not found. "); 
+                       }
+                       else {
+                               // This was a cousin edge.   But before we delete it, we will check to make
+                               // sure it doesn't have a unique-dependency issue (need to check in two directions)
+                               Iterator <String> ntItr1 = startVertDepNTColl.iterator();
+                               if( ntItr1.hasNext() ){
+                                       while( ntItr1.hasNext() ){
+                                               if( ntItr1.next().equals(otherNT) ){
+                                                       throw new AAIException("AAI_6126", "Edge between " + startVertVid + " and " + reqDelConnectedVid +
+                                                                       " cannot be deleted because of a uniqueness-dependancy between nodeTypes, " +
+                                                                       startVertNT + " and " + otherNT); 
+                                               }
+                                       }
+                               }
+
+                               Collection <String> depNTColl =  dbMaps.NodeDependencies.get(otherNT);
+                               Iterator <String> ntItr2 = depNTColl.iterator();
+                               if( ntItr2.hasNext() ){
+                                       while( ntItr2.hasNext() ){
+                                               if( ntItr2.next().equals(startVertNT) ){
+                                                       throw new AAIException("AAI_6126", "Edge between " + startVertVid + " and " + reqDelConnectedVid +
+                                                                       " cannot be deleted because of a uniqueness-dependancy between nodeTypes: " +
+                                                                       otherNT + " and " + startVertNT); 
+                                               }
+                                       }
+                               }
+
+                               // It's OK to delete this edge as requested.
+                               if( ! isFirst ){
+                                       msg = msg + ", ";
+                               }
+                               isFirst = false;
+                               msg = msg + reqDelConnectedVid + "(" + otherNT + ")";
+                               TitanEdge targetDelEdge = cousinVidToEdgeInDbHash.get(reqDelConnectedVid);
+                               DbMeth.removeAaiEdge(transId, fromAppId, graph, targetDelEdge);
+                       }
+               }
+       }
+
+       msg = msg + "]";
+
+       LOGGER.info(msg);
+       
+       return;
+
+}// End deleteEdgeGroup()
+
+
+/**
+ * Gets the edge group.
+ *
+ * @param transId the trans id
+ * @param fromAppId the from app id
+ * @param graph the graph
+ * @param startVert the start vert
+ * @param vidToNodeTypeHash the vid to node type hash
+ * @param vidToVertexHash the vid to vertex hash
+ * @param scope the scope
+ * @param apiVersion the api version
+ * @return void
+ * @throws AAIException the AAI exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+public static void getEdgeGroup( String transId, 
+                                                               String fromAppId, 
+                                                               TitanTransaction graph,  
+                                                               TitanVertex startVert, 
+                                                               HashMap <String,String> vidToNodeTypeHash,
+                                                               HashMap <String,TitanVertex> vidToVertexHash,
+                                                               String scope, 
+                                                               String apiVersion ) throws AAIException, UnsupportedEncodingException{
+
+       LOGGER.debug("scope={}", scope);
+       LOGGER.debug("vid={}", startVert.id().toString());
+       LOGGER.debug("nodetype={}", startVert.property("aai-node-type").orElse(null).toString());
+
+       /*
+        *  scope can be one of these:  
+        *    1) "ONLY_COUSIN_REL"   <-- This is the only one supported for now
+        *    2) "ALL_COUSIN_AND_CHILDREN_REL"
+        *    3) "ONLY_CHILDREN" 
+        *    4) "USES_RESOURCE"
+        *        
+        *   Given a startNode and the scope, we need to return relationships that we find in the DB
+        */
+
+       if( !scope.equals("ONLY_COUSIN_REL") ){
+               throw new AAIException("AAI_6120", "Illegal scope parameter passed: [" + scope + "]."); 
+       }
+
+       //------------------------------------------------------------------------------------------------------------
+       // Grab "first-layer" vertexes from the in the db -- 
+       //        "cousins" => grab all nodes connected to startVertex that have edges with param: isParent = false.
+       //        "children" => grab nodes via out-edge with isParent = true    (NOT YET SUPPORTED)
+       //------------------------------------------------------------------------------------------------------------
+       Iterable<Vertex> qResult = startVert.query().has("isParent",false).vertices();
+       Iterator <Vertex> resultI = qResult.iterator();
+
+       while( resultI.hasNext() ){
+               TitanVertex cousinV = (TitanVertex)resultI.next();
+               //showPropertiesForNode( transId, fromAppId, cousinV );
+
+               String vid = cousinV.id().toString();
+               String noTy = cousinV.<String>property("aai-node-type").orElse(null);
+               vidToNodeTypeHash.put(vid, noTy);
+               vidToVertexHash.put(vid, cousinV);
+
+               LOGGER.debug("Found connected cousin vid(s) in db: " + "[" + cousinV.id().toString() + "]");
+       }
+
+}// End getEdgeGroup()
+
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/DbMeth.java b/aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/DbMeth.java
new file mode 100644 (file)
index 0000000..5951a10
--- /dev/null
@@ -0,0 +1,3643 @@
+/*-
+ * ============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.dbgraphgen;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+
+import org.openecomp.aai.dbmodel.DbEdgeRules;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.ingestModel.DbMaps;
+import org.openecomp.aai.ingestModel.IngestModelMoxyOxm;
+import org.openecomp.aai.serialization.db.EdgeRule;
+import org.openecomp.aai.serialization.db.EdgeRules;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.google.common.net.InetAddresses;
+import com.thinkaurelius.titan.core.TitanEdge;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanTransaction;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+
+/**
+ * General Database-level Utility class.   These methods deal with the database one dataNode / Edge at a time.
+ * Transactions are managed at a higher level by the calling classes by passing in a TitanTransaction object.
+ */
+public class DbMeth{
+
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DbMeth.class);
+       
+       /**
+        * Patch aai node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propHash the prop hash
+        * @param depNodeVal the dep node val
+        * @param apiVersion the api version
+        * @return TitanVertex
+        * @throws AAIException the AAI exception
+        */
+       public static TitanVertex patchAaiNode(String transId, String fromAppId, TitanTransaction graph, String nodeType, 
+                       HashMap <String,Object> propHash, TitanVertex depNodeVal, String apiVersion ) throws AAIException{
+               // If they're calling patchAaiNode, then we only want to add/update the properties that they
+               // pass us in the propHash.  If there are others already in the DB, we leave them alone.
+
+               // Note: to be really official, we'd throw an error if the node wasn't already in the db.
+               boolean[] objectExists = new boolean[1];
+               objectExists[0] = true;
+               Boolean patchOnly = true;
+               TitanVertex tv = persistAaiNodeBASE(transId, fromAppId, graph, nodeType, propHash, depNodeVal, patchOnly, apiVersion, objectExists);
+               return( tv );
+
+       } // end of patchAaiNode()
+       
+       /**
+        * Patch aai node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propHash the prop hash
+        * @param depNodeVal the dep node val
+        * @return the titan vertex
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static TitanVertex patchAaiNode(String transId, String fromAppId, TitanTransaction graph, String nodeType, 
+                       HashMap <String,Object> propHash, TitanVertex depNodeVal) throws AAIException{
+               return patchAaiNode( transId,  fromAppId,  graph,  nodeType, 
+                               propHash,  depNodeVal, null );
+       }
+       
+       /**
+        * Persist aai node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propHash the prop hash
+        * @param depNodeVal the dep node val
+        * @param patchOnly the patch only
+        * @param apiVersion the api version
+        * @return the titan vertex
+        * @throws AAIException the AAI exception
+        */
+       public static TitanVertex persistAaiNode(String transId, String fromAppId, TitanTransaction graph, String nodeType, 
+                       HashMap <String,Object> propHash, TitanVertex depNodeVal, Boolean patchOnly, String apiVersion) throws AAIException{
+               boolean[] objectExists = new boolean[1];
+               objectExists[0] = false;
+               return persistAaiNodeBASE( transId,  fromAppId,  graph,  nodeType, 
+                                propHash,  depNodeVal, patchOnly, apiVersion, objectExists);
+       }
+       
+       /**
+        * Persist aai node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propHash the prop hash
+        * @param addIfNotFound the add if not found
+        * @param depNodeVal the dep node val
+        * @param apiVersion the api version
+        * @return the titan vertex
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static TitanVertex persistAaiNode(String transId, String fromAppId, TitanTransaction graph, String nodeType, 
+                       HashMap <String,Object> propHash, Boolean addIfNotFound, TitanVertex depNodeVal, String apiVersion) throws AAIException{
+               // If they're calling persistAaiNode, then we want to make the Db look like whatever they pass us.  That is, if
+               // there is already a record in the DB, but they do not pass some of the existing properties, they should
+               // be cleared from the DB.    Since we want to take care of all properties, we pass patchOnly = false
+               Boolean patchOnly = false;
+               boolean[] objectExists = new boolean[1];
+               objectExists[0] = false;
+               TitanVertex tv = persistAaiNodeBASE(transId, fromAppId, graph, nodeType, propHash, depNodeVal, patchOnly, apiVersion, objectExists);
+               return( tv );
+       } 
+       
+       /**
+        * Persist aai node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propHash the prop hash
+        * @param addIfNotFound the add if not found
+        * @param depNodeVal the dep node val
+        * @return the titan vertex
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static TitanVertex persistAaiNode(String transId, String fromAppId, TitanTransaction graph, String nodeType, 
+                       HashMap <String,Object> propHash, Boolean addIfNotFound, TitanVertex depNodeVal) throws AAIException{
+               // If they're calling persistAaiNode, then we want to make the Db look like whatever they pass us.  That is, if
+               // there is already a record in the DB, but they do not pass some of the existing properties, they should
+               // be cleared from the DB.    Since we want to take care of all properties, we pass patchOnly = false
+               Boolean patchOnly = false;
+               boolean[] objectExists = new boolean[1];
+               objectExists[0] = false;
+               TitanVertex tv = persistAaiNodeBASE(transId, fromAppId, graph, nodeType, propHash, depNodeVal, patchOnly, null, objectExists);
+               return( tv );
+       } // end of persistAaiNode()
+       
+       /**
+        * Persist aai node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propHash the prop hash
+        * @param addIfNotFound the add if not found
+        * @param depNodeVal the dep node val
+        * @param apiVersion the api version
+        * @param objectExists the object exists
+        * @return TitanVertex
+        * @throws AAIException the AAI exception
+        */
+       public static TitanVertex persistAaiNode(String transId, String fromAppId, TitanTransaction graph, String nodeType, 
+                       HashMap <String,Object> propHash, Boolean addIfNotFound, TitanVertex depNodeVal, String apiVersion, boolean[] objectExists) throws AAIException{
+               Boolean patchOnly = false;
+               // If they're calling persistAaiNode, then we want to make the Db look like whatever they pass us.  That is, if
+               // there is already a record in the DB, but they do not pass some of the existing properties, they should
+               // be cleared from the DB.    Since we want to take care of all properties, we pass patchOnly = false
+               TitanVertex tv = persistAaiNodeBASE(transId, fromAppId, graph, nodeType, propHash, depNodeVal, patchOnly, apiVersion, objectExists, null);
+               return( tv );
+       } 
+       
+       /**
+        * Persist aai node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propHash the prop hash
+        * @param addIfNotFound the add if not found
+        * @param depNodeVal the dep node val
+        * @param apiVersion the api version
+        * @param objectExists the object exists
+        * @param thisNodeVertex the this node vertex
+        * @return the titan vertex
+        * @throws AAIException the AAI exception
+        */
+       public static TitanVertex persistAaiNode(String transId, String fromAppId, TitanTransaction graph, String nodeType, 
+                       HashMap <String,Object> propHash, Boolean addIfNotFound, TitanVertex depNodeVal, String apiVersion, boolean[] objectExists, TitanVertex thisNodeVertex) throws AAIException{
+               Boolean patchOnly = false;
+               // If they're calling persistAaiNode, then we want to make the Db look like whatever they pass us.  That is, if
+               // there is already a record in the DB, but they do not pass some of the existing properties, they should
+               // be cleared from the DB.    Since we want to take care of all properties, we pass patchOnly = false
+               TitanVertex tv = persistAaiNodeBASE(transId, fromAppId, graph, nodeType, propHash, depNodeVal, patchOnly, apiVersion, objectExists, thisNodeVertex);
+               return( tv );
+       } 
+       
+       /**
+        * Persist aai node BASE.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propHash the prop hash
+        * @param depNodeVal the dep node val
+        * @param patchOnly the patch only
+        * @param apiVersion the api version
+        * @param objectExists the object exists
+        * @return the titan vertex
+        * @throws AAIException the AAI exception
+        */
+       public static TitanVertex persistAaiNodeBASE(String transId, String fromAppId, TitanTransaction graph, String nodeType, 
+                       HashMap <String,Object> propHash, TitanVertex depNodeVal, Boolean patchOnly, 
+                       String apiVersion, boolean[] objectExists) throws AAIException{
+               return persistAaiNodeBASE(transId, fromAppId, graph, nodeType, propHash, depNodeVal, patchOnly, apiVersion, objectExists, null);
+       }
+       
+       /**
+        * Persist aai node BASE.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propHash the prop hash
+        * @param depNodeVal the dep node val
+        * @param patchOnly the patch only
+        * @param apiVersion the api version
+        * @param objectExists the object exists
+        * @param thisNodeVertex the this node vertex
+        * @return the titan vertex
+        * @throws AAIException the AAI exception
+        */
+       public static TitanVertex persistAaiNodeBASE(String transId, String fromAppId, TitanTransaction graph, String nodeType, 
+                       HashMap <String,Object> propHash, TitanVertex depNodeVal, Boolean patchOnly, 
+                       String apiVersion, boolean[] objectExists, TitanVertex thisNodeVertex) throws AAIException{
+               
+               if( graph == null ){
+                       throw new AAIException("AAI_6101", "null graph object passed to persistAaiNodeBASE()"); 
+               }
+               
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+               boolean useDepNode = false;
+               String resourceVersion = null;
+               if( propHash.containsKey("resource-version") ){
+                       resourceVersion = (String)(propHash.get("resource-version")); 
+               }       
+               String aaiUniqueKeyVal = null;
+               if( propHash.containsKey("aai-unique-key") ){
+                       // Note -- we are assuming that nobody is monkeying with this.   The 16-07 first-pass theory
+                       //    is that the REST layer is always gonna generate this or pass it through.
+                       aaiUniqueKeyVal = (String)(propHash.get("aai-unique-key")); 
+                       propHash.remove("aai-unique-key");
+               }       
+               
+               if( needsADepNode4Uniqueness(transId, fromAppId, nodeType, apiVersion) ){
+                       // This kind of node needs a dependent node (for uniqueness)
+                       if( depNodeVal == null ){
+                               // They should have passed in the node that this one depends on
+                               throw new AAIException("AAI_6109", "null dependentNode object passed to persistAaiNodeBASE() but " + nodeType + " requires one."); 
+                       }
+                       else if( ! nodeTypeACanDependOnB(transId, fromAppId, nodeType, depNodeVal.<String>property("aai-node-type").orElse(null), apiVersion) ){
+                               // They should have passed in the right type of node as the dependent node
+                               throw new AAIException("AAI_6109", "dependentNode of type " + depNodeVal.<String>property("aai-node-type").orElse(null) + " passed to persistAaiNodeBASE() for nodeType" + nodeType + "."); 
+                       }
+                       useDepNode = true;
+               }
+               else {
+                       depNodeVal = null;
+               }
+               
+               // Note: as of 1607, we no longer validate property names since that's covered by the REST layer.
+               // Same goes for required fields (as of 1602)
+
+               // Special ip-address validation for ipAddr nodes only...   This will go away when we go to YANG and
+               // do validations like this up at that layer.
+               if( nodeType.equals("ipaddress") ){
+                       // Note - this will throw an exception if the ipAddress is using a bad format
+                       ipAddressFormatOK( transId, fromAppId, (String)propHash.get("addr"), (String)propHash.get("version") );
+               }
+
+               // Use the key-fields/dependentNode to check if this is an add or an update
+               // We assume that all NodeTypes at least one key-property defined.  A dependentNode is optional.
+               if( ! dbMaps.NodeKeyProps.containsKey(nodeType) ){
+                       // Problem if no key Properties defined for this nodeType  
+                       String defVer = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP);
+                       throw new AAIException("AAI_6105", "No node-key-properties defined in dbMaps for nodeType = " + nodeType + " (ver=" + defVer + ")"); 
+               }
+
+               Boolean hasAltKey1 = false;
+               HashMap <String,Object>nodeAltKey1PropsHash = new HashMap<String,Object>();
+               Collection <String> altKey1Props = getNodeAltKey1PropNames(transId, fromAppId, nodeType, apiVersion);
+               if( altKey1Props != null ){
+                       Iterator <String> altKey1PropI = altKey1Props.iterator();
+                       while( altKey1PropI.hasNext() ){
+                               String propName = altKey1PropI.next();
+                               // NOTE: alt-keys are not always required fields.  If it is null or blank, we won't 
+                               //      do alt-key checks on it.
+                               Object value = propHash.get(propName); 
+                               if( value != null && !value.toString().equals("") ){
+                                       hasAltKey1 = true;
+                                       nodeAltKey1PropsHash.put(propName, value);
+                               }
+                       }
+               }
+               HashMap <String,Object>nodeKeyPropsHash = new HashMap<String,Object>();
+               Collection <String> keyProps = getNodeKeyPropNames(transId, fromAppId, nodeType, apiVersion);
+               Iterator <String> keyPropI = keyProps.iterator();
+               while( keyPropI.hasNext() ){
+                       String propName = keyPropI.next();
+                       
+                       Object value = propHash.get(propName); 
+                       nodeKeyPropsHash.put(propName, value);
+               }
+
+               // Check if this node is already in the database based on the Primary Key Info
+               TitanVertex existingVert = thisNodeVertex;
+               boolean foundTheNodeInDb = true;
+                       
+               if (existingVert == null) { 
+                       try {
+                               existingVert = getUniqueNode( transId, fromAppId, graph, nodeType, nodeKeyPropsHash, depNodeVal, apiVersion );
+                       }
+                       catch (AAIException e) {
+                               if (e.getErrorObject().getErrorCode().equals("6114")) {
+                                       foundTheNodeInDb = false;
+                               }
+                               else {
+                                       throw e;
+                               }
+                       }
+               }
+                               
+               // this is so the notification knows whether or not the operation was an UPDATE or a CREATe
+               objectExists[0] = foundTheNodeInDb;
+               if( foundTheNodeInDb ){
+                       // A record was found in the DB using the PK.  
+                       if( needToDoResourceVerCheck(apiVersion, patchOnly) ){
+                               // Need to check that they knew what they were updating
+                               String existingResVer = existingVert.<String>property("resource-version").orElse(null);
+                               if( resourceVersion == null || resourceVersion.equals("") ){
+                                       throw new AAIException("AAI_6130", "Resource-version not passed for update of = " + nodeType + ", " + nodeKeyPropsHash.toString()); 
+                               }
+                               else if( (existingResVer != null) && !resourceVersion.equals(existingResVer) ){
+                                       throw new AAIException("AAI_6131", "Resource-version " + resourceVersion + " MISMATCH WITH EXISTING " + existingResVer + " for update of = " + nodeType + ", " + nodeKeyPropsHash.toString()); 
+                               }
+                       }
+                       
+                       // Need to ensure that the Alternate key isn't changing to a value that points to a different existing node.   
+                       // It is ok if it points to nothing -- that would just be an update for this node.   It's also ok if 
+                       // it points to this (existing) node - that just means that it wasn't being updated.
+                       if( hasAltKey1 ){
+                               try {
+                                       TitanVertex chkVert = getUniqueNode( transId, fromAppId, graph, nodeType, nodeAltKey1PropsHash, depNodeVal, apiVersion );
+                                       if( ! chkVert.id().toString().equals(existingVert.id().toString()) ){
+                                               throw new AAIException("AAI_6117", "In-Use AlternateKey value passed for update of nodeType = " + nodeType); 
+                                       }
+                               }
+                               catch (AAIException e) {
+                                       if(! e.getErrorObject().getErrorCode().equals("6114") ){
+                                               throw e;
+                                       }
+                               }
+                       }
+               }
+               else {
+                       // Note not in the DB -- This will be an ADD of a new node
+                       //              a) make sure they didn't say they were just doing "patchOnly" which cannot be an ADD.
+                       //              b) if there is an alternate key, we need to make sure the AK isn't already in use by somebody else.
+                       if( patchOnly ){
+                               String depMsg = "";
+                               if( useDepNode ){
+                                       depMsg = " plus dependent node. ";
+                               }
+                               throw new AAIException("AAI_6114", "Patch Request, but no Node of type " + nodeType + " found for properties: [" + propHash + "] " + depMsg);
+                       }
+                       
+                       if( needToDoResourceVerCheck(apiVersion, patchOnly) && (resourceVersion != null) && !resourceVersion.equals("") ){
+                               throw new AAIException("AAI_6131", "Resource-version was passed in, but this is an ADD of a " + nodeType + ", with these params: " + nodeKeyPropsHash.toString()); 
+                       }
+                       if( hasAltKey1 ){
+                               try {
+                                       getUniqueNode( transId, fromAppId, graph, nodeType, nodeAltKey1PropsHash, depNodeVal, apiVersion );
+                                       // Since the Primary Key for this nodeType wasn't found in the DB yet, the fact that
+                                       // we are able to find a record (no "6114" exception thrown) using the Alternate-Key is an error.  
+                                       // We can't create a new node that uses an AK that's already in use.
+                                       throw new AAIException("AAI_6117", "Conflicting Key and Alternate-Key values passed for add of nodeType = " + nodeType); 
+                               }
+                               catch (AAIException e) {
+                                       if(! e.getErrorObject().getErrorCode().equals("6114") ){
+                                               throw e;
+                                       }
+                               }
+                       }
+               }
+
+               // ------------- Done with checking.  Do the add or update to the dB -----------------------
+
+               if( foundTheNodeInDb ){
+                       long unixTimeNow = System.currentTimeMillis() / 1000L;
+                       // ----- This is an UPDATE ------
+                       
+                       
+                       String existingSourceOfTruth = fromAppId;  // default value if we can't get the old one
+                       Object tmpOb = existingVert.<Object>property("source-of-truth").orElse(null);
+                       if( tmpOb != null ){
+                               existingSourceOfTruth = tmpOb.toString();
+                       }
+                       long existingCreateTs = unixTimeNow;  // default value if we can't get the old one
+                       tmpOb = existingVert.<Object>property("aai-created-ts").orElse(null);
+                       if( tmpOb != null ){
+                               existingCreateTs = (long) tmpOb;
+                       }
+                       
+                       String msg = "UPDATE vertex of type = [" + nodeType + "] "; 
+                       if( useDepNode ){
+                               String depNType = depNodeVal.<String>property("aai-node-type").orElse(null);
+                               HashMap <String, Object> depNodePropKeysHash = getNodeKeyPropHash(transId, fromAppId, graph, depNodeVal);
+                               LOGGER.info("UPDATE existing node: type = " + nodeType + ", key(s) = [" + nodeKeyPropsHash + 
+                                               "] which rides on dependent node: type = " + depNType + ", with key(s) = [" + depNodePropKeysHash + "].");
+                       }
+                       else {
+                               LOGGER.info("UPDATE existing node: type = " + nodeType + ", key(s) = [" + nodeKeyPropsHash + "] (no dep. node).");
+                       }
+                       String removeList = "";
+                       if( ! patchOnly ){
+                               // They are updating an existing record, and they want us to "process all defined properties" (not just patch)   
+                               // So we will see if the node has any properties that were not passed-in.  Those need to be removed.
+                               Collection <String> propCol =  dbMaps.NodeProps.get(nodeType);
+                               Iterator <String> propIter = propCol.iterator();
+                               while( propIter.hasNext() ){
+                                       String propName = propIter.next();
+                                       if( ! propHash.containsKey(propName) && !DbEdgeRules.ReservedPropNames.containsKey(propName)){  
+                                               if( thisPropertyWasPutByNewerVersionOfCode(apiVersion, nodeType, propName) ){
+                                                       //   we must be using an older version of code here - but the property that
+                                                       //   has not been passed in this persist call is one that this older version of
+                                                       //   the database did not know about.  So leave it alone.
+                                               }
+                                               else {
+                                                       removeList = removeList + "," + propName;
+                                                       existingVert.property(propName).remove();
+                                               }
+                                       }
+                               }
+                       }
+                       if( !removeList.equals("") ){
+                               LOGGER.info("Removed these props on update: [" + removeList + "]");
+                       }
+                       for( Map.Entry<String, Object> entry : propHash.entrySet() ){
+                               // update the parameters that have been passed in (except the key-properties)
+                               //                  taking away the key-property check.  We will now allow this since
+                               //                  the keys were used to identify this node, so they should be good and
+                               //                  there are times when Titan resolves conflicts by only using the 
+                               //                  data set in an update - and was losing our key info... 
+                               //                  Similar to the change noted below.
+                               //if( ! nodeKeyPropsHash.containsKey(entry.getKey()) ){
+                               //      existingVert.setProperty( entry.getKey(), entry.getValue() );
+                               //}
+                               if( ! entry.getKey().equals("resource-version") ){
+                                       boolean nonSingleCardinality = false;
+                                       boolean setSoNoDupes = false;
+                                       if( checkPropCardinality(entry.getKey(), "Set") ){
+                                               nonSingleCardinality = true;
+                                               setSoNoDupes = true;
+                                       }
+                                       else if( checkPropCardinality(entry.getKey(), "List") ){
+                                               nonSingleCardinality = true;
+                                       }
+                                       
+                                       Iterator <Object> valIter = null;
+                                       if( nonSingleCardinality ){
+                                               String className = entry.getValue().getClass().getSimpleName();
+                                               if( className.equals("ArrayList") ){
+                                                       valIter = ((ArrayList)(entry.getValue())).iterator();
+                                               }
+                                               else if( className.equals("List") ){
+                                                       valIter = ((List)(entry.getValue())).iterator();
+                                               }
+                                               else if( className.equals("Set") ){
+                                                       valIter = ((Set)(entry.getValue())).iterator();
+                                               }
+                                       }
+                                       
+                                       if( nonSingleCardinality ){
+                                               // This property has Cardinality of List or Set - which need to be handled carefully
+                                               // Note -- for Lists or Sets, we assume they are of dataType String - that is all
+                                               //       the Rest layer supports at the moment (16-02)
+                                               ArrayList <String> currentData = new ArrayList <String> ();
+                                               if( patchOnly ){
+                                                       // When patching - gotta know what's already in the db
+                                                       Iterator<VertexProperty<Object>> existingPropsIter =  (existingVert.properties(entry.getKey()));
+                                                       if( existingPropsIter != null ){
+                                                               while( existingPropsIter.hasNext() ){
+                                                                       String existingVal = existingPropsIter.next().value().toString();
+                                                                       currentData.add( existingVal );
+                                                               }
+                                                       }
+                                               }
+                                               else {
+                                                       // Since this is not a patch-update, we first have to clear out what is currently in the db.
+                                                       existingVert.property(entry.getKey()).remove();
+                                               }
+                                               
+                                               if( valIter != null ){
+                                                       while( valIter.hasNext() ){
+                                                               Object thisVal = valIter.next();        
+                                                               if( setSoNoDupes ){
+                                                                       // For Sets, we need to check that the data isn't already in the db or wasn't passed
+                                                                       // in to us twice in the propHash.  Otherwise Titan throws an exception (instead of just ignoring it...)
+                                                                       if( !currentData.contains(thisVal) ){
+                                                                               // We don't have this data yet, so add it to the Set
+                                                                               existingVert.property( entry.getKey(), thisVal );
+                                                                               currentData.add( thisVal.toString() );
+                                                                       }
+                                                               }
+                                                               else {
+                                                                       // For List data types, it's ok to have duplicate values in the db (why would we want this?)
+                                                                       existingVert.property( entry.getKey(), thisVal );
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       else {
+                                               // This is a normal, "Cardinality = SINGLE" kind of property
+                                               // ResourceVersion is not populated based on passed-in data, it is set along with other internal properties below.
+                                               //Object cleanVal = convertTypeIfNeeded( entry.getKey(), entry.getValue() );
+                                               //existingVert.setProperty( entry.getKey(),  cleanVal );
+                                               // ********************************
+                                               existingVert.property( entry.getKey(), entry.getValue() );
+                                       }
+                               }
+                       }
+
+                       // DEBUG - trying to deal with the case where simultaneous PUTs
+                       //    cause our db to wind up with a vertex that does not have these three properties filled in.
+                       existingVert.property( "aai-node-type", nodeType );
+                       existingVert.property( "aai-created-ts", existingCreateTs );
+                       existingVert.property( "source-of-truth", existingSourceOfTruth );
+                       
+                       if( aaiUniqueKeyVal != null ){
+                               existingVert.property( "aai-unique-key", aaiUniqueKeyVal );
+                       }
+                       
+                       existingVert.property( "aai-last-mod-ts", unixTimeNow );
+                       String resVers = "" + unixTimeNow; 
+                       existingVert.property( "resource-version", resVers );
+                       existingVert.property( "last-mod-source-of-truth", fromAppId );
+                       
+                       LOGGER.info(msg + ", [aai-last-mod-ts]/[" + unixTimeNow + "]");
+                       
+                       return( existingVert );
+               }
+               else{ 
+                       // ----- Not found in the DB, This must be an ADD ------
+                       if( DbEdgeRules.NodeTypeCategory.containsKey(nodeType) ){
+                               throw new AAIException("AAI_6120", "nodeTypeCategory " + nodeType + " cannot be used to ADD a node.  Need to pass a valid nodeType"); 
+                       }
+
+                       TitanVertex tiVnew = graph.addVertex( nodeType );
+
+                       String msg = "ADD vertex of type = [" + nodeType + "] ";       
+                       if( depNodeVal != null ){
+                               String depNType = depNodeVal.<String>property("aai-node-type").orElse(null);
+                               HashMap <String, Object> depNodePropKeysHash = getNodeKeyPropHash(transId, fromAppId, graph, depNodeVal);
+                               msg = msg + " onto dependent node: type = " + depNType + ", which has key(s) = [" + depNodePropKeysHash + 
+                                               "].  New Node Prop/values = ";
+                       }
+                       else {
+                               msg = msg + " Note: no dependent node.  New Node Prop/values = ";
+                       }
+                       boolean first = true;
+                       for( Map.Entry<String, Object> entry : propHash.entrySet() ){
+                               if( ! entry.getKey().equals("resource-version") ){
+                                       if( first ){
+                                               msg = msg + " [" + entry.getKey() + "]/[" + entry.getValue() + "]";
+                                               first = false;
+                                       }
+                                       else {
+                                               msg = msg + ", [" + entry.getKey() + "]/[" + entry.getValue() + "]";
+                                       }
+                                       
+                                       boolean nonSingleCardinality = false;
+                                       boolean setSoNoDupes = false;
+                                       if( checkPropCardinality(entry.getKey(), "Set") ){
+                                               nonSingleCardinality = true;
+                                               setSoNoDupes = true;
+                                       }
+                                       else if( checkPropCardinality(entry.getKey(), "List") ){
+                                               nonSingleCardinality = true;
+                                       }
+                                       
+                                       Iterator <Object> valIter = null;
+                                       if( nonSingleCardinality ){
+                                               String className = entry.getValue().getClass().getSimpleName();
+                                               if( className.equals("ArrayList") ){
+                                                       valIter = ((ArrayList)(entry.getValue())).iterator();
+                                               }
+                                               else if( className.equals("List") ){
+                                                       valIter = ((List)(entry.getValue())).iterator();
+                                               }
+                                               else if( className.equals("Set") ){
+                                                       valIter = ((Set)(entry.getValue())).iterator();
+                                               }
+                                       }
+                                       
+                                       if( nonSingleCardinality ){
+                                               // This property has Cardinality of List or Set - which need to be handled carefully
+                                               ArrayList <String> currentData = new ArrayList <String> ();
+                                               if( valIter != null ){
+                                                       while( valIter.hasNext() ){
+                                                               Object thisVal = valIter.next();        
+                                                               if( setSoNoDupes ){
+                                                                       // For Sets, we need to check that they're not passing us duplicate data in propHash.
+                                                                       // Otherwise Titan throws an exception (instead of just ignoring it...)
+                                                                       if( !currentData.contains(thisVal) ){
+                                                                               // We don't have this data yet, so add it to the Set
+                                                                               tiVnew.property( entry.getKey(), thisVal );
+                                                                               currentData.add( thisVal.toString() );
+                                                                       }
+                                                               }
+                                                               else {
+                                                                       // For List data types, it's ok to have duplicate values in the db (why would we want this?)
+                                                                       tiVnew.property( entry.getKey(), thisVal );
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       else {
+                                               // This is a normal, "Cardinality = SINGLE" kind of property
+                                               // ResourceVersion is not populated based on passed-in data, it is set along with other internal properties below.
+                                               tiVnew.property( entry.getKey(), entry.getValue() );
+                                       }
+                               }
+                       }
+                       
+                       tiVnew.property( "aai-node-type", nodeType );
+                       //long unixTime = System.currentTimeMillis() / 1000L;
+                       long unixTime = System.currentTimeMillis();
+                       tiVnew.property( "aai-created-ts", unixTime );
+                       tiVnew.property( "aai-last-mod-ts", unixTime );
+                       String resVers = "" + unixTime; 
+                       tiVnew.property( "resource-version", resVers );
+                       tiVnew.property( "source-of-truth", fromAppId );
+                       tiVnew.property( "last-mod-source-of-truth", fromAppId );
+                       if( aaiUniqueKeyVal != null ){
+                               tiVnew.property( "aai-unique-key", aaiUniqueKeyVal );
+                       }
+                       
+                       LOGGER.info(msg + ", [aai-created-ts]/[" + unixTime + "]");
+                       return( tiVnew );
+               }
+
+       } // end of persistAaiNodeBASE()
+
+       
+       /**
+        * Need to do resource ver check.
+        *
+        * @param apiVersion the api version
+        * @param patchOnlyFlag the patch only flag
+        * @return the boolean
+        * @throws AAIException the AAI exception
+        */
+       public static Boolean needToDoResourceVerCheck(String apiVersion, Boolean patchOnlyFlag)
+                       throws AAIException{
+               
+               if( patchOnlyFlag ){
+                       // we do not do resource checking for patch requests.
+                       return false;
+               }
+               
+               String resourceCheckOnFlag = AAIConfig.get(AAIConstants.AAI_RESVERSION_ENABLEFLAG);
+               
+               int apiVerInt = cleanUpApiVersion(apiVersion);
+               
+               if( (resourceCheckOnFlag != null) && resourceCheckOnFlag.equals("true") ){
+                       // Only do the check if the resource enable flag is set to "true"
+                       if( apiVerInt > 4 ){
+                               // We're only doing the resource version checks for v5 and later
+                               return true;
+                       }
+               }
+               
+               return false;
+       }// End needToDoResourceVerCheck()
+
+       
+       /**
+        * Clean up api version.
+        *
+        * @param apiVersionString the api version string
+        * @return the int
+        * @throws AAIException the AAI exception
+        */
+       private static int cleanUpApiVersion( String apiVersionString ) throws AAIException {
+               // Note: we expect an apiVersion to start with the letter "v", followed by an integer. 
+               
+               int versionInt = 0;
+               String verStr = apiVersionString;
+               if( (apiVersionString == null) || (apiVersionString.length() < 2) ){
+                       // Passed in version doesn't look right
+                       verStr = org.openecomp.aai.util.AAIApiVersion.get();
+               }
+               versionInt = getVerNumFromVerString( verStr );
+               
+               return versionInt;
+       }
+       
+       /**
+        * Gets the ver num from ver string.
+        *
+        * @param versionString the version string
+        * @return the ver num from ver string
+        * @throws AAIException the AAI exception
+        */
+       private static int getVerNumFromVerString( String versionString )throws AAIException {
+               int versionInt = 0;
+               if( versionString == null || versionString.length() < 2 ){
+                       throw new AAIException("AAI_6121", " Bad Version (format) passed to getVerNumFromVerString: [" + versionString + "]."); 
+               }
+               
+               int strLen = versionString.length();
+               // We assume that a version looks like "v" followed by an integer
+               if( ! versionString.substring(0,1).equals("v") ){
+                       String detail = " Bad Version (format) passed to getVerNumFromVerString: [" + versionString + "]."; 
+                       throw new AAIException("AAI_6121", detail); 
+               }
+               else {
+                       String intPart = versionString.substring(1,strLen);
+                       try {
+                               versionInt = Integer.parseInt( intPart );
+                       }
+                       catch( Exception e ){
+                               String detail = " Bad Version passed to getVerNumFromVerString: [" + versionString + "]."; 
+                               throw new AAIException("AAI_6121", detail);
+                       }
+               }
+               return versionInt;
+       }
+
+       
+       /**
+        * Gets the node key prop names.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @param apiVersion the api version
+        * @return HashMap of keyProperties
+        * @throws AAIException the AAI exception
+        */
+       public static Collection <String> getNodeKeyPropNames( String transId, String fromAppId, String nodeType, String apiVersion ) throws AAIException{
+       
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+               Collection <String> keyProps = new ArrayList <String>();
+               if( dbMaps.NodeKeyProps.containsKey(nodeType) ){
+                       keyProps = dbMaps.NodeKeyProps.get(nodeType);
+               }
+               else if( DbEdgeRules.NodeTypeCategory.containsKey(nodeType) ){
+                       // The passed-in nodeType was really a nodeCategory, so we need to look up the key params
+                       Collection <String> nTypeCatCol = DbEdgeRules.NodeTypeCategory.get(nodeType);
+                       Iterator <String> catItr = nTypeCatCol.iterator();
+                       String catInfo = "";
+                       if( catItr.hasNext() ){
+                               // For now, we only look for one.
+                               catInfo = catItr.next();
+                       }
+                       else {
+                               String defVer = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP);
+                               throw new AAIException("AAI_6105", "Required Property name(s) not found for nodeType = " + nodeType+ " (ver=" + defVer + ")"); 
+                       }
+
+                       String [] flds = catInfo.split(",");
+                       if( flds.length != 4 ){
+                               throw new AAIException("AAI_6121", "Bad EdgeRule.NodeTypeCategory data for nodeType = [" + nodeType + "]."); 
+                       }
+
+                       String keyPropsString = flds[0];
+                       String [] propNames = keyPropsString.split("\\|");
+                       for( int i = 0; i < propNames.length; i++ ){
+                               keyProps.add(propNames[i]);
+                       }
+               }
+               else {
+                       String defVer = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP);
+                       throw new AAIException("AAI_6105", "Required Property name(s) not found for nodeType = " + nodeType+ " (ver=" + defVer + ")"); 
+               }
+
+               return keyProps;
+
+       }// end of getNodeKeyPropNames
+       
+       /**
+        * Gets the node key prop names.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @return the node key prop names
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static Collection <String> getNodeKeyPropNames( String transId, String fromAppId, String nodeType ) throws AAIException{
+               return getNodeKeyPropNames(  transId,  fromAppId,  nodeType, null);
+       }
+
+       /**
+        * Gets the node alt key 1 prop names.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @param apiVersion the api version
+        * @return HashMap of keyProperties
+        * @throws AAIException the AAI exception
+        */
+       public static Collection <String> getNodeAltKey1PropNames( String transId, String fromAppId, String nodeType, String apiVersion ) throws AAIException{
+
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+               Collection <String> altKey1Props = new ArrayList <String>();
+               if( dbMaps.NodeAltKey1Props.containsKey(nodeType) ){
+                       altKey1Props = dbMaps.NodeAltKey1Props.get(nodeType);
+               }
+               else if( DbEdgeRules.NodeTypeCategory.containsKey(nodeType) ){
+                       // The passed-in nodeType was really a nodeCategory, so we need to look up the key params
+                       Collection <String> nTypeCatCol = DbEdgeRules.NodeTypeCategory.get(nodeType);
+                       Iterator <String> catItr = nTypeCatCol.iterator();
+                       String catInfo = "";
+                       if( catItr.hasNext() ){
+                               catInfo = catItr.next();
+                               String [] flds = catInfo.split(",");
+                               if( flds.length != 4 ){
+                                       throw new AAIException("AAI_6121", "Bad EdgeRule.NodeTypeCategory data (itemCount=" + flds.length + ") for nodeType = [" + nodeType + "]."); 
+                               }
+
+                               String altKeyPropsString = flds[1];
+                               String [] propNames = altKeyPropsString.split("\\|");
+                               for( int i = 0; i < propNames.length; i++ ){
+                                       altKey1Props.add(propNames[i]);
+                               }
+                       }
+               }
+
+               return altKey1Props;
+
+       }// end of getNodeAltKey1PropNames
+       
+       /**
+        * Gets the node alt key 1 prop names.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @return the node alt key 1 prop names
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static Collection <String> getNodeAltKey1PropNames( String transId, String fromAppId, String nodeType ) throws AAIException{
+               return getNodeAltKey1PropNames(  transId,  fromAppId,  nodeType, null);
+       }
+
+
+       /**
+        * Gets the unique node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param keyPropsHash the key props hash
+        * @param depNodeVal the dep node val
+        * @param apiVersion the api version
+        * @return TitanVertex
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static TitanVertex getUniqueNode( String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> keyPropsHash, TitanVertex depNodeVal, String apiVersion )         throws AAIException{
+               
+               // NOTE - this is really for use by the PersistNode method -- it is looking to see if
+               //     a node exists in the database given either Primary or Alternate Key data and dependent
+               //     node data (if required for uniqueness).
+
+               // Note - the passed in nodeType could really be a nodeTypeCategory ---
+               Boolean nodeTypeIsCategory = DbEdgeRules.NodeTypeCategory.containsKey(nodeType);
+
+               Boolean useDepNode = false;
+               if( needsADepNode4Uniqueness(transId, fromAppId, nodeType, apiVersion) ){
+                       // This kind of node depends on another node for uniqueness
+                       if( depNodeVal == null ){
+                               // They should have passed in the node that this one depends on
+                               throw new AAIException("AAI_6109", "null dependentNode object passed to getUniqueNode() but " + nodeType + " requires one."); 
+                       }
+                       else if( ! nodeTypeACanDependOnB(transId, fromAppId, nodeType, depNodeVal.<String>property("aai-node-type").orElse(null), apiVersion) ){        
+                               // They should have passed in the right type of node as the dependent node
+                               throw new AAIException("AAI_6109", "dependentNode of type " + depNodeVal.<String>property("aai-node-type").orElse(null) + " passed to getUniqueNode() for nodeType" + nodeType + ".\n"); 
+                       }
+                       useDepNode = true;
+               }
+               else {
+                       depNodeVal = null;
+               }
+
+               // We assume that all NodeTypes have at least one key-property defined.  A dependentNode is optional.
+               // Note - instead of key-properties (the primary key properties), a user could pass
+               //        alternate-key values if they are defined for the nodeType.
+               ArrayList<String> kName = new ArrayList<String>();
+               ArrayList<Object> kVal = new ArrayList<Object>();
+
+               Collection <String> keyProps = getNodeKeyPropNames(transId, fromAppId, nodeType, apiVersion);
+               Iterator <String> keyPropI = keyProps.iterator();
+               Boolean haveSomePrimKeyProps = false;
+               Boolean primaryKeyComplete = true;
+               while( keyPropI.hasNext() ){
+                       haveSomePrimKeyProps = true;
+                       
+                       String propName = keyPropI.next();
+                       if( ! keyPropsHash.containsKey(propName) ){
+                               primaryKeyComplete = false;
+                       }
+                       else {
+                               Object valObj = keyPropsHash.get(propName);
+                               if( valObj == null ){
+                                       primaryKeyComplete = false;
+                               }
+                               else {
+                                       String value = valObj.toString();
+                                       if( value == null || value.equals("") ){
+                                               // They passed the property name, but no value
+                                               primaryKeyComplete = false;
+                                       }
+                               }
+                       }
+               }
+               
+               int i = -1;
+               if( haveSomePrimKeyProps && primaryKeyComplete ){
+                       keyPropI = keyProps.iterator();
+                       while( keyPropI.hasNext() ){
+                               String propName = keyPropI.next();
+                               String value = (keyPropsHash.get(propName)).toString();
+                               i++;
+                               kName.add(i, propName);
+                               kVal.add(i, (Object)value);
+                       }
+               }
+               else {
+                       // See if they're using the alternate key
+                       Collection <String> altKey1Props = getNodeAltKey1PropNames(transId, fromAppId, nodeType, apiVersion);
+                       Iterator <String> altKey1PropI = altKey1Props.iterator();
+                       Boolean haveSomeAltKey1Props = false;
+                       Boolean altKey1Complete = true;
+                       while( altKey1PropI.hasNext() ){
+                               haveSomeAltKey1Props = true;
+                               String propName = altKey1PropI.next();
+                               if( ! keyPropsHash.containsKey(propName) ){
+                                       altKey1Complete = false;
+                               }
+                               else {
+                                       Object valObj = keyPropsHash.get(propName);
+                                       if( valObj == null ){
+                                               altKey1Complete = false;
+                                       }
+                                       else {
+                                               String value = valObj.toString();
+                                               if( value == null || value.equals("") ){
+                                                       // They passed the property name, but no value
+                                                       altKey1Complete = false;
+                                               }
+                                       }
+                               }
+                       }
+                       if( haveSomeAltKey1Props && altKey1Complete ){
+                               altKey1PropI = altKey1Props.iterator();
+                               while( altKey1PropI.hasNext() ){
+                                       String propName = altKey1PropI.next();
+                                       String value = (keyPropsHash.get(propName)).toString();
+                                       i++;
+                                       kName.add(i, propName);
+                                       kVal.add(i, (Object)value);
+                               }
+                       }
+               }
+
+               int topPropIndex = i;
+               TitanVertex tiV = null;
+               String propsAndValuesForMsg = "";
+               if( !useDepNode ){ 
+                       // There is no node that this type of node depends on, so we can look for it based 
+                       //    solely on the Aai-defined key fields.
+                       Iterable <?> verts = null;
+
+                       if( topPropIndex == -1 ){
+                               // Problem if no key Properties defined for this nodeType  
+                               String defVer = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP);
+                               throw new AAIException("AAI_6105", "Bad or Incomplete Key Property params: (" + keyPropsHash.toString() + 
+                                               ") for nodeType: " + nodeType + " (ver=" + defVer + ")"); 
+                       }
+                       else if( topPropIndex == 0 ){
+                               if (nodeTypeIsCategory) // dont know real type
+                                       verts= graph.query().has(kName.get(0),kVal.get(0)).vertices();
+                               else // need this to find dvs switch: dvs.switch-name and port-group.switch-name issue
+                                       verts= graph.query().has(kName.get(0),kVal.get(0)).has("aai-node-type",nodeType).vertices();
+                               propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ") ";
+                       }       
+                       else if( topPropIndex == 1 ){
+                               verts =  graph.query().has(kName.get(0),kVal.get(0)).has(kName.get(1),kVal.get(1)).vertices();
+                               propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ", " 
+                                               + kName.get(1) + " = " + kVal.get(1) + ") ";
+                       }                       
+                       else if( topPropIndex == 2 ){
+                               verts= graph.query().has(kName.get(0),kVal.get(0)).has(kName.get(1),kVal.get(1)).has(kName.get(2),kVal.get(2)).vertices();
+                               propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ", " 
+                                               + kName.get(1) + " = " + kVal.get(1) + ", " 
+                                               + kName.get(2) + " = " + kVal.get(2) +  ") ";
+                       }       
+                       else if( topPropIndex == 3 ){
+                               verts= graph.query().has(kName.get(0),kVal.get(0)).has(kName.get(1),kVal.get(1)).has(kName.get(2),kVal.get(2)).has(kName.get(3),kVal.get(3)).vertices();
+                               propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ", " 
+                                               + kName.get(1) + " = " + kVal.get(1) + ", " 
+                                               + kName.get(2) + " = " + kVal.get(2) + ", " 
+                                               + kName.get(3) + " = " + kVal.get(3) +  ") ";
+                       }                       
+                       else {
+                               String emsg = " We only support 4 keys per nodeType for now \n";
+                               throw new AAIException("AAI_6114", emsg); 
+                       }
+
+                       Iterator <?> vertI = verts.iterator();
+                       if( vertI != null && vertI.hasNext()) {
+                               // We found a vertex that meets the input criteria. 
+                               tiV = (TitanVertex) vertI.next();
+
+                               if( vertI.hasNext() ){
+                                       // Since this routine is looking for a unique node for the given input values, if  
+                                       // more than one is found - it's a problem.
+                                       throw new AAIException("AAI_6112", "More than one Node found by getUniqueNode for params: " + propsAndValuesForMsg); 
+                               }
+                       } 
+                       else {
+                               // No Vertex was found for this key - throw a not-found exception
+                               throw new AAIException("AAI_6114", "No Node of type " + nodeType + " found for properties: " + propsAndValuesForMsg);
+                       }
+               }
+               else {
+                       // Need to use the dependent vertex to look for this one.
+                       // filter this to the actual keys because
+                       HashMap<String,Object> onlyKeysHash = new HashMap<String,Object>();
+                       
+                       Collection <String> onlyKeyProps = getNodeKeyPropNames(transId, fromAppId, nodeType, apiVersion);
+                       
+                       Iterator <String> onlyKeyPropsI = onlyKeyProps.iterator();
+                       
+                       while( onlyKeyPropsI.hasNext() ){
+                               String keyName = onlyKeyPropsI.next();
+                               onlyKeysHash.put(keyName, keyPropsHash.get(keyName));
+                       }
+
+                       propsAndValuesForMsg = onlyKeysHash.toString() + " combined with a Dependent [" + depNodeVal.<String>property("aai-node-type").orElse(null) + "] node."; 
+                       ArrayList<TitanVertex> resultList = DbMeth.getConnectedNodes(transId, fromAppId, graph, nodeType, onlyKeysHash, 
+                                       depNodeVal, apiVersion, false);
+                       if( resultList.size() > 1 ){
+                               // More than one vertex found when we thought there should only be one.
+                               throw new AAIException("AAI_6112", "More than one Node found by getUniqueNode for params: " + propsAndValuesForMsg);  
+                       }
+                       else if( resultList.size() == 1 ){
+                               tiV = resultList.get(0);
+                       }
+               }
+
+               if( tiV == null ){
+                       // No Vertex was found for this key - throw a not-found exception
+                       throw new AAIException("AAI_6114", "No Node of type " + nodeType + " found for properties: " + propsAndValuesForMsg);
+               }
+               else {
+                       if( !DbEdgeRules.NodeTypeCategory.containsKey(nodeType) ){
+                               // The nodeType passed in was a real one, not a nodeTypeCategory, so we will
+                               // use it as part of the query to make sure we find the right type of node.
+                               // This can be an issue if they're using nodeTypes covered by a nodeTypeCategory but
+                               // pass in the wrong nodeType.  We don't want them to ask for one thing and get the other.
+                               String foundNodeType = tiV.<String>property("aai-node-type").orElse(null);
+                               if( foundNodeType != null && !foundNodeType.equals(nodeType) ){
+                                       throw new AAIException("AAI_6114", "No Node of type " + nodeType + " found for properties: " + propsAndValuesForMsg + " (did find a " + foundNodeType + " though.)");
+                               }
+                       }
+                       
+                       return tiV;
+               }
+
+       }// End of getUniqueNode() 
+
+       /**
+        * Gets the unique node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param keyPropsHash the key props hash
+        * @param depNodeVal the dep node val
+        * @return the unique node
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static TitanVertex getUniqueNode( String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> keyPropsHash, TitanVertex depNodeVal)     throws AAIException {
+               return getUniqueNode( transId, fromAppId, graph, nodeType,
+                               keyPropsHash,  depNodeVal, null );
+       }
+       // End getUniqueNode()
+
+
+       /**
+        * Gets the unique node with dep params.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param nodePropsHash the node props hash
+        * @param apiVersion the api version
+        * @return TitanVertex
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static TitanVertex getUniqueNodeWithDepParams( String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> nodePropsHash, String apiVersion ) 
+                                       throws AAIException{
+               /*
+                * This method uses the nodePropsHash to walk back over dependent nodes until it finds one that
+                * does not depend on any other for uniqueness.   It uses the getUniqueNode() method as it finds
+                * dependent nodes.   NOTE -- it is passed a hash of all the nodeProperties -- for itself and
+                * for any dependent nodes that it will need to find.   There are some types of nodes that can
+                * depend on more than one node, we assume that there wouldn't be a case where BOTH types of
+                * dependent nodes are in the trail that we need to traverse.  Ie. an ipaddress can depend on
+                * either a vserver or pserver.  NOTE this case can now happen -- nodePropsHash
+                * should now be sent as a LinkedHashMap in this case so we can search in order. 
+                */
+
+               // NOTE ALSO -- We're currently supporting 6 layers of dependency.   We never thought there would be this
+               //       many layers before hitting a node-type that would be uniquely identifiable on it's own.   So the
+               //       code is a little ugly with all these nested if-then-else's.   Since we're supporting so many
+               //       layers, it should be re-written so we can support "n" layers instead of having to go in hear
+               //       and adding code...   But as of 15-07, we really don't NEED more than 5.
+
+               // NOTE: The passed in nodeType could really be a nodeTypeCategory -- 
+               //       The calls to figureDepNodeTypeForRequest() below will deal with it for the dep nodes, the 
+               //       call to getUniqueNode() takes care of it for the node itself.
+
+               TitanVertex nullVert = null;
+               String depNodeType = figureDepNodeTypeForRequest( transId, fromAppId, nodeType, nodePropsHash, apiVersion );
+               if( depNodeType.equals("")){
+                       // This kind of node does not depend on another node for uniqueness, so 
+                       // we can just use the "getUniqueNode()" method to get it.
+                       HashMap <String,Object> thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, nodeType, nodePropsHash, apiVersion);
+                       return( getUniqueNode(transId, fromAppId, graph, nodeType, thisNodeTypeParamHash, nullVert, apiVersion) );
+               }
+               else {
+                       // Will need to find the second-layer dependent node
+                       String secondLayerDepNodeType = figureDepNodeTypeForRequest( transId, fromAppId, depNodeType, nodePropsHash, apiVersion );
+                       if( secondLayerDepNodeType.equals("")){
+                               // This second-layer kind of node does not depend on another node for uniqueness.
+                               // So once we find the second-layer node, we can use it to get the top-layer guy.
+                               HashMap <String,Object> thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, depNodeType, nodePropsHash, apiVersion);
+                               TitanVertex secLayerDepVert = getUniqueNode(transId, fromAppId, graph, depNodeType, thisNodeTypeParamHash, nullVert, apiVersion);
+
+                               thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, nodeType, nodePropsHash, apiVersion);
+                               return( getUniqueNode(transId, fromAppId, graph, nodeType, thisNodeTypeParamHash, secLayerDepVert, apiVersion) );
+                       }
+                       else {
+                               // Will need to find the third-layer dependent node
+                               ///  String thirdLayerDepNodeType = dbMaps.NodeDependencies.get(secondLayerDepNodeType);
+                               String thirdLayerDepNodeType = figureDepNodeTypeForRequest( transId, fromAppId, secondLayerDepNodeType, nodePropsHash, apiVersion );
+
+                               if( thirdLayerDepNodeType.equals("")){
+                                       // This third-layer kind of node does not depend on another node for uniqueness.
+                                       // So we can find it, and then use it to find the second-layer and then use that to find the top guy.
+                                       HashMap <String,Object> thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, secondLayerDepNodeType, nodePropsHash, apiVersion);
+                                       TitanVertex thirdLayerDepVert = getUniqueNode(transId, fromAppId, graph, secondLayerDepNodeType, thisNodeTypeParamHash, nullVert, apiVersion);
+
+                                       thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, depNodeType, nodePropsHash, apiVersion);
+                                       TitanVertex secLayerDepVert = getUniqueNode(transId, fromAppId, graph, depNodeType, thisNodeTypeParamHash, thirdLayerDepVert, apiVersion);
+
+                                       thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, nodeType, nodePropsHash, apiVersion);
+
+                                       return( getUniqueNode(transId, fromAppId, graph, nodeType, thisNodeTypeParamHash, secLayerDepVert, apiVersion) );
+                               }
+                               else {
+                                       // Will need to find the third-layer dependent node
+                                       String forthLayerDepNodeType = figureDepNodeTypeForRequest( transId, fromAppId, thirdLayerDepNodeType, nodePropsHash, apiVersion );
+                                       if( forthLayerDepNodeType == null || forthLayerDepNodeType.equals("")){
+                                               // This forth-layer kind of node does not depend on another node for uniqueness.
+                                               // So we can find it, and then use it to find the third, then second-layer and then use that to find the top guy.
+                                               HashMap <String,Object> thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, thirdLayerDepNodeType, nodePropsHash, apiVersion);
+                                               TitanVertex forthLayerDepVert = getUniqueNode(transId, fromAppId, graph, thirdLayerDepNodeType, thisNodeTypeParamHash, nullVert, apiVersion);
+
+                                               thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, secondLayerDepNodeType, nodePropsHash, apiVersion);
+                                               TitanVertex thirdLayerDepVert = getUniqueNode(transId, fromAppId, graph, secondLayerDepNodeType, thisNodeTypeParamHash, forthLayerDepVert, apiVersion);
+
+                                               thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, depNodeType, nodePropsHash, apiVersion);
+                                               TitanVertex secLayerDepVert = getUniqueNode(transId, fromAppId, graph, depNodeType, thisNodeTypeParamHash, thirdLayerDepVert, apiVersion);
+
+                                               thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, nodeType, nodePropsHash, apiVersion);
+                                               return( getUniqueNode(transId, fromAppId, graph, nodeType, thisNodeTypeParamHash, secLayerDepVert, apiVersion) );
+                                       }
+                                       else {
+                                               // Will need to find the forth-layer dependent node
+                                               String fifthLayerDepNodeType = figureDepNodeTypeForRequest( transId, fromAppId, forthLayerDepNodeType, nodePropsHash, apiVersion );
+                                               if( fifthLayerDepNodeType == null || fifthLayerDepNodeType.equals("")){
+                                                       // This fifth-layer kind of node does not depend on another node for uniqueness.
+                                                       // So we can find it, and then use it to find the forth, third, then second-layer and then use that to find the top guy.
+                                                       HashMap <String,Object> thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, forthLayerDepNodeType, nodePropsHash, apiVersion);
+                                                       TitanVertex fifthLayerDepVert = getUniqueNode(transId, fromAppId, graph, forthLayerDepNodeType, thisNodeTypeParamHash, nullVert, apiVersion);
+
+                                                       thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, thirdLayerDepNodeType, nodePropsHash, apiVersion);
+                                                       TitanVertex forthLayerDepVert = getUniqueNode(transId, fromAppId, graph, thirdLayerDepNodeType, thisNodeTypeParamHash, fifthLayerDepVert, apiVersion);
+
+                                                       thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, secondLayerDepNodeType, nodePropsHash, apiVersion);
+                                                       TitanVertex thirdLayerDepVert = getUniqueNode(transId, fromAppId, graph, secondLayerDepNodeType, thisNodeTypeParamHash, forthLayerDepVert, apiVersion);
+
+                                                       thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, depNodeType, nodePropsHash, apiVersion);
+                                                       TitanVertex secLayerDepVert = getUniqueNode(transId, fromAppId, graph, depNodeType, thisNodeTypeParamHash, thirdLayerDepVert, apiVersion);
+
+                                                       thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, nodeType, nodePropsHash, apiVersion);
+                                                       return( getUniqueNode(transId, fromAppId, graph, nodeType, thisNodeTypeParamHash, secLayerDepVert, apiVersion) );
+                                               }
+                                               else {
+                                                       // Will need to find the fifth-layer dependent node
+                                                       String sixthLayerDepNodeType = figureDepNodeTypeForRequest( transId, fromAppId, fifthLayerDepNodeType, nodePropsHash, apiVersion );
+                                                       if( sixthLayerDepNodeType == null || sixthLayerDepNodeType.equals("")){
+                                                               // This six-layer kind of node does not depend on another node for uniqueness.
+                                                               // So we can find it, and then use it to find the fifth, forth, third, then second-layer and then use that to find the top guy.
+                                                               HashMap <String,Object> thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, fifthLayerDepNodeType, nodePropsHash, apiVersion);
+                                                               TitanVertex sixthLayerDepVert = getUniqueNode(transId, fromAppId, graph, fifthLayerDepNodeType, thisNodeTypeParamHash, nullVert, apiVersion);
+
+                                                               thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, forthLayerDepNodeType, nodePropsHash, apiVersion);
+                                                               TitanVertex fifthLayerDepVert = getUniqueNode(transId, fromAppId, graph, forthLayerDepNodeType, thisNodeTypeParamHash, sixthLayerDepVert, apiVersion);
+
+                                                               thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, thirdLayerDepNodeType, nodePropsHash, apiVersion);
+                                                               TitanVertex forthLayerDepVert = getUniqueNode(transId, fromAppId, graph, thirdLayerDepNodeType, thisNodeTypeParamHash, fifthLayerDepVert, apiVersion);
+
+                                                               thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, secondLayerDepNodeType, nodePropsHash, apiVersion);
+                                                               TitanVertex thirdLayerDepVert = getUniqueNode(transId, fromAppId, graph, secondLayerDepNodeType, thisNodeTypeParamHash, forthLayerDepVert, apiVersion);
+
+                                                               thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, depNodeType, nodePropsHash, apiVersion);
+                                                               TitanVertex secLayerDepVert = getUniqueNode(transId, fromAppId, graph, depNodeType, thisNodeTypeParamHash, thirdLayerDepVert, apiVersion);
+
+                                                               thisNodeTypeParamHash = getThisNodeTypeParams(transId, fromAppId, nodeType, nodePropsHash, apiVersion);
+                                                               return( getUniqueNode(transId, fromAppId, graph, nodeType, thisNodeTypeParamHash, secLayerDepVert, apiVersion) );
+                                                       }
+                                                       else {
+                                                               // We don't currently support more layers.  We can later if we need to.
+                                                               // Hopefully, we'll never need to go this deep -- there should be unique keys in there somewhere! 
+                                                               throw new AAIException("AAI_6114", "CODE-LIMITATION - Can't resolve dependant node layers for nodeType = " + nodeType); 
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       } // End getUniqueNodeWithDepParams()
+       
+       /**
+        * Gets the unique node with dep params.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param nodePropsHash the node props hash
+        * @return the unique node with dep params
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static TitanVertex getUniqueNodeWithDepParams( String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> nodePropsHash ) throws AAIException {
+               return getUniqueNodeWithDepParams(transId, fromAppId, graph, nodeType, nodePropsHash, null);
+       }
+
+
+       /**
+        * Gets the this node type params.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param targetNodeType the target node type
+        * @param passedHash the passed hash
+        * @param apiVersion the api version
+        * @return the this node type params
+        * @throws AAIException the AAI exception
+        */
+       private static HashMap <String, Object> getThisNodeTypeParams(String transId, String fromAppId, String targetNodeType, 
+                       HashMap<String,Object> passedHash, String apiVersion )throws AAIException{
+               /*
+                * For the passed-in hash, each key is assumed to look like, "nodeType.paramName".  We want to 
+                * pick out the entries that match the targetNodeType and return those with the values they go with.  The
+                * returned keys will have the "nodeType." stripped off.   
+                * 
+                * NOTE  - the nodeType passed to this method could actually be a nodeTypeCategory.  Just keepin it ugly.
+                */
+
+               if( passedHash == null ){
+                       throw new AAIException("AAI_6120", "Bad param:  null passedHash "); 
+               }
+
+               String targetNodeTypeCat = "";
+               if( DbEdgeRules.NodeTypeCatMap.containsKey(targetNodeType) ){
+                       targetNodeTypeCat = DbEdgeRules.NodeTypeCatMap.get(targetNodeType);
+               }
+
+               HashMap <String,Object> returnHash = new HashMap <String,Object> ();
+               Iterator <Map.Entry<String,Object>>it = passedHash.entrySet().iterator();
+               while( it.hasNext() ){
+                       Map.Entry <String,Object>pairs = (Map.Entry<String,Object>)it.next();
+                       String k = (pairs.getKey()).toString();
+                       int periodLoc = k.indexOf(".");
+                       if( periodLoc <= 0 ){
+                               throw new AAIException("AAI_6120", "Bad filter param key passed in: [" + k + "].  Expected format = [nodeName.paramName]\n"); 
+                       }
+                       else {
+                               String nty = k.substring(0,periodLoc);
+                               String paramName = k.substring(periodLoc + 1);
+                               if( nty.equals(targetNodeType) || (!targetNodeTypeCat.equals("") && nty.equals(targetNodeTypeCat)) ){
+                                       String newK = paramName;
+                                       returnHash.put( newK,pairs.getValue() );
+                               }
+                       }
+               }
+
+               //aaiLogger.debug(logline, " - end ");
+               return returnHash;
+
+       }// End of getThisNodeTypeParams()
+       
+       /**
+        * Gets the this node type params.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param targetNodeType the target node type
+        * @param passedHash the passed hash
+        * @return the this node type params
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       private static HashMap <String, Object> getThisNodeTypeParams(String transId, String fromAppId, String targetNodeType, 
+                       HashMap<String,Object> passedHash )throws AAIException{
+               return getThisNodeTypeParams( transId,  fromAppId, targetNodeType, 
+                                passedHash, null);
+               
+       }
+
+       /**
+        * Gets the dep node types.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @param apiVersion the api version
+        * @return the dep node types
+        * @throws AAIException the AAI exception
+        */
+       public static ArrayList <String> getDepNodeTypes(String transId, String fromAppId, String nodeType, String apiVersion)throws AAIException{
+               /*
+                * This returns any nodeTypes that this nodeType can be dependent on.  A particular instance of a node will only
+                * depend on one other node - we don't currently support dependence on multiple nodes.
+                */
+                       
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+
+               ArrayList <String> depNodeTypeL = new ArrayList <String> ();
+               if( !DbEdgeRules.NodeTypeCategory.containsKey(nodeType) ){
+                       // This is a good-ole nodeType
+                       Collection <String> depNTColl =  dbMaps.NodeDependencies.get(nodeType);
+                       Iterator <String> ntItr = depNTColl.iterator();
+                       while( ntItr.hasNext() ){
+                               depNodeTypeL.add(ntItr.next());
+                       }
+               }
+               else {
+                       // The passed-in nodeType must really be a nodeTypeCategory
+                       Collection <String> nTypeCatCol = DbEdgeRules.NodeTypeCategory.get(nodeType);
+                       Iterator <String> catItr = nTypeCatCol.iterator();
+                       String catInfo = "";
+                       if( catItr.hasNext() ){
+                               // For now, we only look for one.
+                               catInfo = catItr.next();
+                       }
+                       else {
+                               throw new AAIException("AAI_6121", "Error getting DbEdgeRules.NodeTypeCategory info for nodeTypeCat = " + nodeType); 
+                       }
+
+                       String [] flds = catInfo.split(",");
+                       if( flds.length != 4 ){
+                               throw new AAIException("AAI_6121", "Bad EdgeRule.NodeTypeCategory data (itemCount=" + flds.length + ") for nodeType = [" + nodeType + "]."); 
+                       }
+
+                       String nodeTypesString = flds[0];
+                       String  hasDepNodes = flds[3];
+                       if( hasDepNodes.equals("true") ){
+                               String [] ntNames = nodeTypesString.split("\\|");
+                               for( int i = 0; i < ntNames.length; i++ ){
+                                       Collection <String> depNTColl =  dbMaps.NodeDependencies.get(nodeType);
+                                       Iterator <String> ntItr = depNTColl.iterator();
+                                       while( ntItr.hasNext() ){
+                                               String depNode = ntItr.next();
+                                               if( !depNodeTypeL.contains(depNode) ){
+                                                       depNodeTypeL.add(depNode);
+                                               }
+                                       }
+                               }       
+                       }
+               }
+
+
+               return depNodeTypeL;
+
+       }// End getDepNodeTypes()
+       
+       /**
+        * Gets the dep node types.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @return the dep node types
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static ArrayList <String> getDepNodeTypes(String transId, String fromAppId, String nodeType)throws AAIException{
+               return getDepNodeTypes( transId,  fromAppId,  nodeType, null);
+       }
+
+       /**
+        * Gets the default delete scope.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @param apiVersion the api version
+        * @return the default delete scope
+        * @throws AAIException the AAI exception
+        */
+       private static String getDefaultDeleteScope(String transId, String fromAppId, String nodeType, String apiVersion)throws AAIException{
+
+               // At some point we may have different delete rules for different services, so this is
+               // a list for now even thought there's only one scope per nodeType.
+               Collection <String> scopeList = DbEdgeRules.DefaultDeleteScope.get(nodeType);
+               if( scopeList.isEmpty() ){
+                       throw new AAIException("AAI_6121", "No default deleteScope found for nodeType = [" + nodeType + "] "); 
+               }
+               else {
+                       Iterator <String> ito = scopeList.iterator();
+                       return ito.next();
+               }
+
+       }// End getDefaultDeleteScope()
+       
+       /**
+        * Gets the default delete scope.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @return the default delete scope
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       private static String getDefaultDeleteScope(String transId, String fromAppId, String nodeType)throws AAIException{
+               return getDefaultDeleteScope( transId,  fromAppId,  nodeType, null);
+       }
+
+       /**
+        * Needs A dep node 4 uniqueness.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @param apiVersion the api version
+        * @return the boolean
+        * @throws AAIException the AAI exception
+        */
+       public static Boolean needsADepNode4Uniqueness(String transId, String fromAppId, String nodeType, String apiVersion)throws AAIException{
+               // Note: the passed in nodeType could really be a nodeTypeCategory.  That is handled by getDepNodeTypes()
+
+               ArrayList <String> depList = getDepNodeTypes(transId, fromAppId, nodeType, apiVersion);
+               if( depList.isEmpty() ){
+                       return false;
+               }
+               else {
+                       return true;
+               }
+
+       }// End needsADepNode4Uniqueness()
+       
+       /**
+        * Needs A dep node 4 uniqueness.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @return the boolean
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       private static Boolean needsADepNode4Uniqueness(String transId, String fromAppId, String nodeType)throws AAIException{
+               return needsADepNode4Uniqueness( transId,  fromAppId,  nodeType,  null);
+       }
+
+       /**
+        * Node type A can depend on B.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeTypeA the node type A
+        * @param nodeTypeB the node type B
+        * @param apiVersion the api version
+        * @return the boolean
+        * @throws AAIException the AAI exception
+        */
+       public static Boolean nodeTypeACanDependOnB(String transId, String fromAppId, String nodeTypeA, String nodeTypeB, String apiVersion)
+                       throws AAIException{
+               // Note: the passed in nodeType could really be a nodeTypeCategory.  That is handled by getDepNodeTypes()
+
+               ArrayList <String> depList = getDepNodeTypes(transId, fromAppId, nodeTypeA, apiVersion);
+               if( depList.isEmpty() ){
+                       return false;
+               }
+               else if( depList.contains(nodeTypeB) ){
+                       return true;
+               }
+               else { 
+                       return false;
+               }
+
+       }// End nodeTypeACanDependOnB()
+       
+       /**
+        * Node type A can depend on B.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeTypeA the node type A
+        * @param nodeTypeB the node type B
+        * @return the boolean
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       private static Boolean nodeTypeACanDependOnB(String transId, String fromAppId, String nodeTypeA, String nodeTypeB)
+                       throws AAIException{
+               return nodeTypeACanDependOnB( transId,  fromAppId,  nodeTypeA,  nodeTypeB, null);
+       }
+
+       /**
+        * Figure dep node type for request.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @param requestParamHash the request param hash
+        * @param apiVersion the api version
+        * @return the string
+        * @throws AAIException the AAI exception
+        */
+       public static String figureDepNodeTypeForRequest(String transId, String fromAppId, String nodeType, 
+                       HashMap<String,Object> requestParamHash, String apiVersion )throws AAIException{
+               /*
+                * This is ugly.   But if the passed-in nodeType is dependent on another nodeType for 
+                * uniqueness, we need to return what that dependent node-type is.  The ugly comes in
+                * because a node can be dependent on more than one type of node.   So, to tell which one
+                * is going to apply, we root through the passed request parameters to see which of 
+                * the possible dependent node types is being used.
+                * Note -- if there comes a day when there are so many dependencies that the request could
+                * have more than one that match -- Then we need to think up something new.   But for now,
+                * we have to assume that if there are more than one legal dep-node-types, only one will
+                * be represented in the requestHash data.  >>> NOTE >>> That day has come.  For
+                * the upstreamers will send in a LinkedHashMap instead of just an unordered
+                * HashMap so we can look in order for the dependent node.
+                * 
+                */
+
+               if( requestParamHash == null ){
+                       throw new AAIException("AAI_6120", "Bad param:  null requestParamHash "); 
+               }
+
+               ArrayList <String> depNodeTypes = getDepNodeTypes(transId, fromAppId, nodeType, apiVersion);
+               if( depNodeTypes.isEmpty() ){
+                       // This kind of node is not dependent on any other
+                       //aaiLogger.debug(logline, " (not dependent) - end ");
+                       return "";
+               }
+               else if( depNodeTypes.size() == 1 ){
+                       // This kind of node can only depend on one other nodeType - so return that.
+                       //aaiLogger.debug(logline, " (depends on " + depNodeTypes.get(0) + " - end ");
+                       return depNodeTypes.get(0);
+               }
+               else {
+                       // We need to look to find the first of the dep-node types that is represented in the passed-in
+                       // request data.  That will be the one we need to use.
+
+                       // first find out what node-types are represented in the requestHash
+                       
+                       Iterator <Map.Entry<String,Object>>it = requestParamHash.entrySet().iterator();
+                       while( it.hasNext() ){
+                               Map.Entry <String,Object>pairs = (Map.Entry<String,Object>)it.next();
+                               String k = (pairs.getKey()).toString();
+                               int periodLoc = k.indexOf(".");
+                               if( periodLoc <= 0 ){
+                                       throw new AAIException("AAI_6120", "Bad filter param key passed in: [" + k + "].  Expected format = [nodeName.paramName]\n"); 
+                               }
+                               else {
+                                       String nty = k.substring(0,periodLoc);
+                                       if( depNodeTypes.contains(nty) ){
+                                               // This is the first possible dep. node type we've found for the passed in data set
+                                               return nty;
+                                       }
+                               }
+                       }
+
+               }
+
+               // It's not an error if none is found - the caller needs to deal with cases where there
+               // should be a dep. node identified but isn't.
+               //aaiLogger.debug(logline, " no dep NT found - end ");
+               return "";
+
+       }// End of figureDepNodeTypeForRequest()
+       
+       /**
+        * Figure dep node type for request.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @param requestParamHash the request param hash
+        * @return the string
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static String figureDepNodeTypeForRequest(String transId, String fromAppId, String nodeType, 
+                       HashMap<String,Object> requestParamHash )throws AAIException{
+                return figureDepNodeTypeForRequest( transId,  fromAppId,  nodeType, requestParamHash, null);
+       }
+       
+       /**
+        * Detach connected nodes.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propFilterHash the prop filter hash
+        * @param startNodeVal the start node val
+        * @param autoDeleteOrphans the auto delete orphans
+        * @param apiVersion the api version
+        * @return deletedNodeCount
+        * @throws AAIException the AAI exception
+        */
+       public static int detachConnectedNodes( String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> propFilterHash, TitanVertex startNodeVal, boolean autoDeleteOrphans, String apiVersion ) throws AAIException{
+
+               /*  Find nodes that are attached to this node which meet the nodeType/filterParams criteria.
+                *  Remove the edges that go to those nodes.
+                *  If that turns any of the nodes into an orphan, then delete it if the autoDeleteOrphans flag is set.
+                *  Return a count of how many nodes were actually deleted (not just detached).
+                */
+
+               int deletedCount = 0;
+
+               if( startNodeVal == null ){
+                       // They should have passed in the node that this query starts from
+                       throw new AAIException("AAI_6109", "null startNode object passed to detachConnectedNodes()."); 
+               }
+
+               // We want to loop through the connected Nodes that we found.
+               // For each connected Node, we'll get the all edges that start from that node and look for the one
+               //     that connects back to our startNode.
+               // Only delete the edge that connects back to our startNode.
+               // then autoDeleteOrphans flag is set, then delete the connectedNode if it's now orphaned.
+               //      
+
+               String startNodeVId =  startNodeVal.id().toString();
+               ArrayList<TitanVertex> conNodeList = getConnectedNodes( transId, fromAppId, graph, nodeType, propFilterHash, startNodeVal, apiVersion, false );
+               Iterator<TitanVertex> conVIter = conNodeList.iterator();
+               while( conVIter.hasNext() ){            
+                       TitanVertex connectedVert = conVIter.next();
+                       boolean isFirstOne = true;
+                       Iterator<Edge> eI = connectedVert.edges(Direction.BOTH);
+                       while( eI.hasNext() ){
+                               TitanEdge ed = (TitanEdge) eI.next();
+                               TitanVertex otherVtx = (TitanVertex) ed.otherVertex(connectedVert);
+                               String otherSideLookingBackVId =  otherVtx.id().toString();
+                               if( startNodeVId.equals(otherSideLookingBackVId) ){
+                                       // This is an edge from the connected node back to our starting node
+                                       if( isFirstOne && !eI.hasNext() && autoDeleteOrphans ){
+                                               // This was the one and only edge for this connectedNode, so 
+                                               // delete the node and edge since flag was set 
+                                               String resVers = connectedVert.<String>property("resource-version").orElse(null);
+                                               removeAaiNode( transId, fromAppId, graph, connectedVert,  "USE_DEFAULT", apiVersion, resVers);
+                                               deletedCount = deletedCount + 1;
+                                       }
+                                       else {
+                                               removeAaiEdge( transId, fromAppId, graph, ed );
+                                       }
+                               }
+                               isFirstOne = false;
+                       }
+               }
+               return deletedCount;
+
+       } // end of detachConnectedNodes()
+
+
+
+       /**
+        * Detach connected nodes.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propFilterHash the prop filter hash
+        * @param startNodeVal the start node val
+        * @param autoDeleteOrphans the auto delete orphans
+        * @return the int
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static int detachConnectedNodes( String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> propFilterHash, TitanVertex startNodeVal, boolean autoDeleteOrphans ) throws AAIException{
+               return detachConnectedNodes(  transId,  fromAppId,  graph,  nodeType,
+                               propFilterHash,  startNodeVal,  autoDeleteOrphans, null);
+       }
+       
+       /**
+        * Gets the nodes.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propFilterHash the prop filter hash
+        * @param noFilterOnPurpose the no filter on purpose
+        * @param apiVersion the api version
+        * @return ArrayList<TitanVertex>
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static ArrayList<TitanVertex> getNodes( String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> propFilterHash, Boolean noFilterOnPurpose, String apiVersion ) throws AAIException{
+               boolean skipGroomingFlag = true; 
+               // we will only do real-time grooming if a system variable is set, telling us not to skip it.
+               String skipGroomingStr = AAIConstants.AAI_SKIPREALTIME_GROOMING;
+               if( skipGroomingStr.equals("false") ){
+                       skipGroomingFlag = false;
+               }
+               return( getNodes(transId, fromAppId, graph, nodeType, propFilterHash, noFilterOnPurpose, apiVersion, skipGroomingFlag) );
+       }
+       
+       /**
+        * Gets the nodes.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propFilterHash the prop filter hash
+        * @param noFilterOnPurpose the no filter on purpose
+        * @param apiVersion the api version
+        * @param skipGroomCheck the skip groom check
+        * @return ArrayList<TitanVertex>
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static ArrayList<TitanVertex> getNodes( String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> propFilterHash, Boolean noFilterOnPurpose, String apiVersion, boolean skipGroomCheck ) 
+                                       throws AAIException{
+               //  Note - the skipGroomCheck flag is set to true when the DataGrooming tool is using this method to collect
+               //     node data.  When the grooming tool is collecting data, we don't want any nodes skipped, because we
+               //     want details about what nodes/edges are bad - more detail than the check in this method does
+               //     as it checks if a node is ok to return to a caller.
+               
+               /* Use the nodeType + filterParams to find nodes.    
+                */
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+               ArrayList<TitanVertex> returnVertList = new ArrayList<TitanVertex>();
+               if( nodeType == null || nodeType.equals("") ){
+                       // They should have passed in a nodeType
+                       throw new AAIException("AAI_6118", "Required field: nodeType not passed to getNodes()."); 
+               }
+
+               if( !noFilterOnPurpose && (propFilterHash == null || propFilterHash.isEmpty()) ){
+                       // They should have passed at least one property to filter on
+                       throw new AAIException("AAI_6118", "Required field: propFilterHash not passed to getNodes()."); 
+               }
+
+               ArrayList<String> kName = new ArrayList<String>();
+               ArrayList<Object> kVal = new ArrayList<Object>();
+               int i = -1;
+               Collection <String> indexedProps =  dbMaps.NodeMapIndexedProps.get(nodeType); 
+               // First loop through to pick up the indexed-properties if there are any being used
+
+               if( propFilterHash != null ){
+                       Iterator <?> it = propFilterHash.entrySet().iterator();
+                       while( it.hasNext() ){
+                               Map.Entry<?,?> propEntry = (Map.Entry<?,?>) it.next();
+                               String propName = (propEntry.getKey()).toString();
+                               // Don't allow search on properties that do not have SINGLE cardinality
+                               if( !checkPropCardinality(propName, "Set") && !checkPropCardinality(propName, "List")  ){
+                                       if( indexedProps.contains(propName) ){
+                                               i++;
+                                               kName.add(i, propName);
+                                               kVal.add(i, (Object)propEntry.getValue());
+                                       }
+                               }
+                       }
+
+                       // Now go through again and pick up the non-indexed properties
+                       it = propFilterHash.entrySet().iterator();
+                       while( it.hasNext() ){
+                               Map.Entry <?,?> propEntry = (Map.Entry<?,?>)it.next();
+                               String propName = (propEntry.getKey()).toString();
+                               // Don't allow search on properties that do not have SINGLE cardinality
+                               if( !checkPropCardinality(propName, "Set") && !checkPropCardinality(propName, "List")  ){
+                                       if( ! indexedProps.contains(propName) ){
+                                               i++;
+                                               kName.add(i, propName);
+                                               kVal.add(i, (Object)propEntry.getValue());
+                                       }
+                               }
+                       }
+               }
+
+               Iterable <?> verts = null;
+               String propsAndValuesForMsg = "";
+               int topPropIndex = i;
+               if( topPropIndex == -1 ){
+                       // No Filtering -- just go get them all
+                       verts= graph.query().has("aai-node-type",nodeType).vertices();
+                       propsAndValuesForMsg = " ( no filter props ) ";
+               }       
+               else if( topPropIndex == 0 ){
+                       verts= graph.query().has(kName.get(0),kVal.get(0)).has("aai-node-type",nodeType).vertices();
+                       propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ") ";
+               }       
+               else if( topPropIndex == 1 ){
+                       verts= graph.query().has(kName.get(0),kVal.get(0)).has(kName.get(1),kVal.get(1)).has("aai-node-type",nodeType).vertices();
+                       propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ", " 
+                                       + kName.get(1) + " = " + kVal.get(1) + ") ";
+               }                       
+               else if( topPropIndex == 2 ){
+                       verts= graph.query().has(kName.get(0),kVal.get(0)).has(kName.get(1),kVal.get(1)).has(kName.get(2),kVal.get(2)).has("aai-node-type",nodeType).vertices();
+                       propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ", " 
+                                       + kName.get(1) + " = " + kVal.get(1) + ", " 
+                                       + kName.get(2) + " = " + kVal.get(2) +  ") ";
+               }       
+               else if( topPropIndex == 3 ){
+                       verts= graph.query().has(kName.get(0),kVal.get(0)).has(kName.get(1),kVal.get(1)).has(kName.get(2),kVal.get(2)).has(kName.get(3),kVal.get(3)).has("aai-node-type",nodeType).vertices();
+                       propsAndValuesForMsg = " (" + kName.get(0) + " = " + kVal.get(0) + ", " 
+                                       + kName.get(1) + " = " + kVal.get(1) + ", " 
+                                       + kName.get(2) + " = " + kVal.get(2) + ", " 
+                                       + kName.get(3) + " = " + kVal.get(3) +  ") ";
+               }                       
+               else {
+                       String emsg = " -- Sorry -- we only support 4 filter properties in getNodes() for now... \n";
+                       throw new AAIException("AAI_6114", emsg); 
+               }   
+               if( verts != null ){
+                       // We did find some matching vertices
+                       Iterator <?> it = verts.iterator();
+                       while( it.hasNext() ){
+                               TitanVertex v = (TitanVertex)it.next();
+                               
+                               if( skipGroomCheck ){
+                                       // Good or bad, just return everything we find
+                                       returnVertList.add( v );
+                               }
+                               else {
+                                       // Weed out any bad vertices we find
+                                       if( thisVertexNotReachable(transId, fromAppId, graph, v, apiVersion) ){
+                                               LOGGER.info("IN-LINE GROOMING - Unreachable Node DETECTED > skipping it. ");
+                                       }
+                                       else if( thisVertexHasBadEdges(transId, fromAppId, graph, v, apiVersion) ){
+                                               LOGGER.info("IN-LINE GROOMING - BAD EDGE DETECTED > skipping vtxId = [" + v.id() + "] ");
+                                       }
+                                       else if( thisVertexIsAPhantom(transId, fromAppId, graph, v, apiVersion) ){
+                                               LOGGER.info("IN-LINE GROOMING - BAD NODE DETECTED > skipping vtxId = [" + v.id() + "] ");
+                                       }
+                                       else {
+                                               returnVertList.add( v );
+                                       }
+                               }
+                       }
+               }
+               
+               return returnVertList;
+       }
+       
+       /**
+        * Gets the nodes.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propFilterHash the prop filter hash
+        * @param noFilterOnPurpose the no filter on purpose
+        * @return the nodes
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static ArrayList<TitanVertex> getNodes( String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> propFilterHash, Boolean noFilterOnPurpose ) throws AAIException{
+               return getNodes(transId,  fromAppId,  graph,  nodeType,
+                               propFilterHash,  noFilterOnPurpose,  null );
+       }
+       // End of getNodes()
+
+
+       /**
+        * Gets the connected children.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param startVtx the start vtx
+        * @param limitToThisNodeType the limit to this node type
+        * @return ArrayList <TitanVertex>
+        * @throws AAIException the AAI exception
+        */
+       public static ArrayList<TitanVertex> getConnectedChildren( String transId, String fromAppId, TitanTransaction graph, 
+                       TitanVertex startVtx, String limitToThisNodeType ) throws AAIException{
+               
+               // Just get child nodes (ie. other end of an OUT edge that is tagged as a parent/Child edge)
+                
+               ArrayList <TitanVertex> childList = new ArrayList <TitanVertex> ();
+               Boolean doNodeTypeCheck = false;
+               if( limitToThisNodeType != null && ! limitToThisNodeType.equals("") ){
+                       doNodeTypeCheck = true;
+               }
+               
+               
+               List<Vertex> verts = graph.traversal().V(startVtx).union(__.outE().has("isParent-REV", true).inV(), __.inE().has("isParent", true).outV()).toList();
+               TitanVertex tmpVtx = null;
+               int vertsSize = verts.size();
+               for (int i = 0; i < vertsSize; i++){
+                       tmpVtx = (TitanVertex) verts.get(i);
+                       if( ! doNodeTypeCheck ){ 
+                               childList.add(tmpVtx);
+                       }
+                       else {
+                               String tmpNT = tmpVtx.<String>property("aai-node-type").orElse(null);
+                               if( tmpNT != null && tmpNT.equals(limitToThisNodeType) ){
+                                       childList.add(tmpVtx);
+                               }
+                       }
+               }
+               
+               return childList;               
+
+       }// End of getConnectedChildren()
+
+
+
+       /**
+        * Gets the connected nodes.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propFilterHash the prop filter hash
+        * @param startNodeVal the start node val
+        * @param apiVersion the api version
+        * @param excludeRecurComingIn the exclude recur coming in
+        * @return ArrayList <TitanVertex>
+        * @throws AAIException the AAI exception
+        */
+       public static ArrayList<TitanVertex> getConnectedNodes( String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> propFilterHash, TitanVertex startNodeVal, String apiVersion, Boolean excludeRecurComingIn ) throws AAIException{
+               
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               /* Get (almost) all the nodes that are connected to this vertex.  
+                * Narrow down what is returned using optional filter parameters nodeType and propFilterHash
+                * NOTE - the default behavior has changed slightly.  For start-Nodes that
+                *        can be recursivly connected, this method will only bring back the same kind of
+                *        connected node by following an OUT edge.   Ie. if the start node is an "model-element", 
+                *        then this method will only follow OUT edges to get to other "model-element" type nodes.
+                */
+
+               String startNodeNT = "";
+               if( startNodeVal == null ){
+                       // They should have passed in the node that this query starts from
+                       throw new AAIException("AAI_6109", "null startNode object passed to getConnectedNodes()."); 
+               }       
+               else {
+                       startNodeNT = startNodeVal.<String>property("aai-node-type").orElse(null);
+               }
+               
+               boolean nodeTypeFilter = false;
+               if( nodeType != null && !nodeType.equals("") ){
+                       // They want to filter using nodeType
+                       if( ! dbMaps.NodeProps.containsKey(nodeType) ){
+                               throw new AAIException("AAI_6115", "Unrecognized nodeType [" + nodeType + "] passed to getConnectedNodes()."); 
+                       }
+                       nodeTypeFilter = true;
+               }  
+               
+               ArrayList <String> excludeVidList = new <String> ArrayList ();
+               if( DbEdgeRules.CanBeRecursiveNT.containsKey(startNodeNT) && excludeRecurComingIn ){
+                       // If we're starting on a nodeType that supports recursion, then find any connected
+                       // nodes that are coming from IN edges so we can exclude them later.
+                       
+                       Iterable <?> vertsR = startNodeVal.query().direction(Direction.IN).vertices();
+                       Iterator <?> vertIR = vertsR.iterator();
+                       while( vertIR != null && vertIR.hasNext() ){
+                               TitanVertex tmpVertIN = (TitanVertex) vertIR.next();
+                               String tmpNT = tmpVertIN.<String>property("aai-node-type").orElse(null);
+                               if( tmpNT != null && tmpNT.equals(startNodeNT) ){
+                                       // We're on a nodetype that supports recursion (like model-element) and we've
+                                       // found an connected Node of this same type on an IN edge - put this 
+                                       // on our excludeList.
+                                       excludeVidList.add( tmpVertIN.id().toString() );
+                               }
+                       }
+               }
+       
+               boolean propertyFilter = false;
+               if( propFilterHash != null && !propFilterHash.isEmpty() ){
+                       // They want to filter using some properties
+                       Iterator <?> it = propFilterHash.entrySet().iterator();
+                       while( it.hasNext() ){
+                               Map.Entry<?,?> propEntry = (Map.Entry<?,?>)it.next();
+                               String propName = (propEntry.getKey()).toString();
+                               if( ! dbMaps.NodeProps.containsValue(propName) ){
+                                       throw new AAIException("AAI_6116", "Unrecognized property name [" + propName + "] passed to getConnectedNodes()."); 
+                               }
+                               // Don't allow search on properties that do not have SINGLE cardinality
+                               if( !checkPropCardinality(propName, "Set") && !checkPropCardinality(propName, "List")  ){
+                                       propertyFilter = true;
+                               }
+                       }
+               }
+               // If filter-properties were passed in, then look for nodes that have those values.
+               ArrayList<TitanVertex> returnVertList = new ArrayList<TitanVertex>();
+               Iterable<TitanVertex> qResult = null;
+               Iterator<TitanVertex> resultI = null;
+               try {
+                       qResult = startNodeVal.query().vertices();
+                       resultI = qResult.iterator();
+               }
+               catch( NullPointerException npe ){
+                       throw new AAIException("AAI_6125", "Titan null pointer exception trying to get nodes connected to vertexId = " + 
+                                       startNodeVal.id() + ", aai-node-type = [" + startNodeVal.property("aai-node-type") + "]."); 
+               }
+
+               while( resultI != null && resultI.hasNext() ){
+                       boolean addThisOne = true;
+                       TitanVertex tmpV = (TitanVertex)resultI.next();                 
+                       if( tmpV == null ){
+                               LOGGER.info("Titan gave a null vertex when looking for nodes connected to vertexId = " + 
+                                               startNodeVal.id() + ", aai-node-type = [" + startNodeVal.property("aai-node-type") + "].");
+                               // Note - we will skip this one, but try to return any others that we find.
+                               addThisOne = false;
+                       }
+
+               else {
+                               String tmpVid = tmpV.id().toString();
+                               if( nodeTypeFilter ){
+                                       Object nto = tmpV.<Object>property("aai-node-type").orElse(null);
+                                       if( nto == null || !nto.toString().equals(nodeType) ){ 
+                                               //LOGGER.info("Found a connected vertex (vertexId = " + 
+                                               //              tmpVid + "), but we will not collect it.  It had aai-node-type [" +
+                                               //              nto + "], we are looking for [" + nodeType + "]. ");
+                                               // Note - we will skip this one, but try to return any others that we find.
+                                               addThisOne = false;
+                                       }
+                               }
+                               
+                               if( excludeVidList.contains(tmpVid) ){
+                                       LOGGER.info("Found a connected vertex (vertexId = " + 
+                                                       tmpVid + "), but will exclude it since it is on an IN edge and this nodeType " +
+                                                       startNodeNT + " can be recursively attached.");
+                                       // Note - we will skip this one, but try to return any others that we find.
+                                       addThisOne = false;
+                               }
+                       
+                               if( propertyFilter ){
+                                       Iterator <?> it = propFilterHash.entrySet().iterator();
+                                       while( it.hasNext() ){
+                                               Map.Entry <?,?>propEntry = (Map.Entry<?,?>)it.next();
+                                               String propName = (propEntry.getKey()).toString();
+                                               if( checkPropCardinality(propName, "Set") || checkPropCardinality(propName, "List")  ){
+                                                       // Don't allow search on properties that do not have SINGLE cardinality
+                                                       continue;
+                                               }
+                                               Object propVal =  propEntry.getValue();
+                                               Object foundVal = tmpV.<Object>property(propName).orElse(null);
+                                               if( foundVal != null && propVal != null && !foundVal.toString().equals(propVal.toString()) ){
+                                                       addThisOne = false;
+                                                       break;
+                                               }
+                                               else if( (foundVal == null && propVal != null) || (foundVal != null && propVal == null) ){
+                                                       addThisOne = false;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       if( addThisOne ){
+                               // This node passed the tests -- put it on the return List
+                               returnVertList.add( (TitanVertex)tmpV );
+                       }
+               }
+               //aaiLogger.debug(logline, " end ");
+               return returnVertList;
+
+       }// End of getConnectedNodes()
+
+
+       /**
+        * Gets the connected nodes.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propFilterHash the prop filter hash
+        * @param startNodeVal the start node val
+        * @param apiVersion the api version
+        * @return the connected nodes
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static ArrayList<TitanVertex> getConnectedNodes(String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> propFilterHash, TitanVertex startNodeVal, String apiVersion ) throws AAIException {
+               return getConnectedNodes( transId,  fromAppId,  graph,  nodeType,
+                               propFilterHash,  startNodeVal,  apiVersion, true );
+       }
+       
+       /**
+        * Gets the connected nodes.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param nodeType the node type
+        * @param propFilterHash the prop filter hash
+        * @param startNodeVal the start node val
+        * @return the connected nodes
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static ArrayList<TitanVertex> getConnectedNodes(String transId, String fromAppId, TitanTransaction graph, String nodeType,
+                       HashMap<String,Object> propFilterHash, TitanVertex startNodeVal ) throws AAIException {
+               return getConnectedNodes( transId,  fromAppId,  graph,  nodeType,
+                               propFilterHash,  startNodeVal,  null, true );
+
+       }
+       
+       /**
+        * Ip address format OK.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param addrVal the addr val
+        * @param addrVer the addr ver
+        * @param apiVersion the api version
+        * @return Boolean
+        * @throws AAIException the AAI exception
+        */
+       public static Boolean ipAddressFormatOK(String transId, String fromAppId, String addrVal, String addrVer, String apiVersion) throws AAIException{
+
+               /* NOTE -- the google methods we use do not allow leading zeros in ipV4 addresses. 
+                *     So it will reject, "22.33.44.001"
+                */
+
+               if( addrVal == null ){
+                       throw new AAIException("AAI_6120", "Bad data (addrVal = null) passed to ipAddressFormatOK()"); 
+               }
+               else if( addrVer == null ){
+                       throw new AAIException("AAI_6120", "Bad data (addrType = null) passed to ipAddressFormatOK()"); 
+               }
+
+               Boolean retVal = false;
+               Boolean lookingForV4 = false;
+               Boolean lookingForV6 = false;
+               InetAddress inetAddr = null;
+
+               if( addrVer.equalsIgnoreCase("v4") || addrVer.equals("ipv4") || addrVer.equals("4")){
+                       lookingForV4 = true;
+               }
+               else if( addrVer.equalsIgnoreCase("v6") || addrVer.equals("ipv6") || addrVer.equals("6")){
+                       lookingForV6 = true;
+               }
+               else {
+                       throw new AAIException("AAI_6120", " Bad data for addressVersion [" + addrVer + "] passed to ipAddressFormatOK()"); 
+               }
+
+               try {
+                       inetAddr = InetAddresses.forString(addrVal);
+                       if( inetAddr instanceof Inet4Address ){
+                               if( lookingForV4 ){
+                                       retVal = true;
+                               }
+                               else {
+                                       throw new AAIException("AAI_6120", "Bad data. Address is a V4, but addressType said it should be V6.  [" 
+                                                       + addrVal + "], [" + addrVer + "] passed to ipAddressFormatOK()"); 
+                               }
+                       }
+                       else if( inetAddr instanceof Inet6Address ){
+                               if( lookingForV6 ){
+                                       retVal = true;
+                               }
+                               else {
+                                       throw new AAIException("AAI_6120", "Bad data. Address is a V6, but addressType said it should be V4.  [" 
+                                                       + addrVal + "], [" + addrVer + "] passed to ipAddressFormatOK()."); 
+                               }
+                       }        
+               } 
+               catch (IllegalArgumentException e) {
+                       throw new AAIException("AAI_6120", "Badly formed ip-address:  [" + addrVal + "] passed to ipAddressFormatOK()"); 
+               }
+
+               return retVal;
+
+       }//end of ipAddressFormatOk()
+       
+       /**
+        * Ip address format OK.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param addrVal the addr val
+        * @param addrVer the addr ver
+        * @return the boolean
+        * @throws AAIException the AAI exception
+        */
+       public static Boolean ipAddressFormatOK(String transId, String fromAppId, String addrVal, String addrVer) throws AAIException{
+               return ipAddressFormatOK( transId,  fromAppId,  addrVal,  addrVer, null);
+       }
+       
+       /**
+        * Save aai edge to db.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param edgeLabel the edge label
+        * @param outV the out V
+        * @param inV the in V
+        * @param propHash the prop hash
+        * @param apiVersion the api version
+        * @return TitanEdge
+        * @throws AAIException the AAI exception
+        */
+       private static TitanEdge saveAaiEdgeToDb(String transId, String fromAppId, TitanTransaction graph, String edgeLabel, 
+                       TitanVertex outV, TitanVertex inV, HashMap <String,Object> propHash, String apiVersion) throws AAIException{
+
+               // If this edge doesn't exist yet, then create it.
+
+               // NOTE - the Titan javaDoc says that there might not always be an id for a node.
+               //   This is the internal-titan-unique-id, not any of our data.
+               //   Not sure how to know when it might be there and when it might not?!
+               //   So far, it has worked for all my testing, but this might warrant some
+               //   further investigation.
+
+               TitanEdge existingEdge = null;
+               String inVId =  inV.id().toString();
+               Iterator <Edge> eI = outV.edges(Direction.BOTH, edgeLabel);
+               while( eI.hasNext() ){
+                       TitanEdge ed = (TitanEdge) eI.next();
+                       TitanVertex otherVtx = (TitanVertex) ed.otherVertex(outV);
+                       if( (otherVtx.id().toString()).equals(inVId) ){
+                               // NOTE -?- Not sure -- at some point we might want to check the edgeLabels also since  we might
+                               //   want to allow two different-type edges between the same two vertexes?  (or maybe not.)
+                               existingEdge = ed;
+                               break;
+                       }
+               }
+
+               if( existingEdge != null ){
+                       // This is just an UPDATE
+                       for( Map.Entry<String, Object> entry : propHash.entrySet() ){
+                               LOGGER.debug("update edge property/val = [" + entry.getKey() + "]/[" + entry.getValue() + "]");
+                               existingEdge.property( entry.getKey(), entry.getValue() );
+                       }
+
+                       return( existingEdge );
+               }
+               else {
+                       // This is an ADD
+                       
+                       // Uniqueness double-check.   This is just to catch the possibility that at the transaction layer,
+                       //    if data came in for two identical nodes that point to the same dependant node (for uniqueness), 
+                       //    we would only be able to catch the problem at the time the edge to the second node is added.   
+                       //    For example - if they had a VM and then got a request to add two ipAddress nodes, but some 
+                       //    bad data was passed and those two ipAddress nodes were identical -- we'd want to catch it.
+                       String outV_NType = outV.<String>property("aai-node-type").orElse(null);
+                       String inV_NType = inV.<String>property("aai-node-type").orElse(null);
+                       if( needsADepNode4Uniqueness(transId, fromAppId, outV_NType, apiVersion)  
+                                       &&  nodeTypeACanDependOnB(transId, fromAppId, outV_NType, inV_NType, apiVersion) ){
+                               // The out-Vertex has a uniqueness dependency on the in-vertex
+                               // Make sure we haven't already added an node/edge like this in this transaction
+                               HashMap <String, Object> nodeKeyPropsHash = getNodeKeyPropHash(transId, fromAppId, graph, outV); 
+                               ArrayList<TitanVertex> resultList = new ArrayList<TitanVertex>();
+                               resultList = DbMeth.getConnectedNodes("transId", "fromAppId", graph, outV_NType, nodeKeyPropsHash, inV, apiVersion, false);
+                               if( resultList.size() > 0 ){
+                                       String propInfo = "";
+                                       if( nodeKeyPropsHash != null ){
+                                               propInfo = nodeKeyPropsHash.toString();
+                                       }
+                                       throw new AAIException("AAI_6117", "Failed to add edge.  This node (" + inV_NType + ") already has an edge to a " + outV_NType + 
+                                                       " node with kepProps [" + propInfo + "]");  
+                               }
+                       }
+                       else if( needsADepNode4Uniqueness(transId, fromAppId, inV_NType, apiVersion)  
+                                       &&  nodeTypeACanDependOnB(transId, fromAppId, inV_NType, outV_NType, apiVersion) ){     
+                               // The in-Vertex has a uniqueness dependency on the out-vertex
+                               // Make sure we haven't already added an node/edge like this in this transaction
+                               HashMap <String, Object> nodeKeyPropsHash = getNodeKeyPropHash(transId, fromAppId, graph, inV);
+                               ArrayList<TitanVertex> resultList = new ArrayList<TitanVertex>();
+                               resultList = DbMeth.getConnectedNodes("transId", "fromAppId", graph, inV_NType, nodeKeyPropsHash, outV, apiVersion, false);
+                               if( resultList.size() > 0 ){
+                                       String propInfo = "";
+                                       if( nodeKeyPropsHash != null ){
+                                               propInfo = nodeKeyPropsHash.toString();
+                                       }
+                                       throw new AAIException("AAI_6117", "Failed to add edge.  This node (" + outV_NType + ") already has an edge to a " + inV_NType + 
+                                                       " node with kepProps [" + propInfo + "]");  
+                               }
+                       }
+                       
+                       
+                       // We're good to go to add this edge
+
+                       TitanEdge tEdge =  outV.addEdge( edgeLabel, inV );
+                       // Add the properties to the new Edge
+                       for( Map.Entry<String, Object> entry : propHash.entrySet() ){
+                               tEdge.property( entry.getKey(), entry.getValue() );
+                       }
+                       
+                       // For (resource-id updates) we need to "touch" the vertices on each side of the edge so
+                       // anybody working on one of those vertices will know that something (ADDing this edge) has happened.
+                       touchVertex( transId, fromAppId, inV );
+                       touchVertex( transId, fromAppId, outV );
+                       
+                       return tEdge;
+               }
+
+       }// End saveAaiEdgeToDb()
+
+       
+       
+       /**
+        * Derive edge rule key for this edge.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param tEdge the t edge
+        * @return String - key to look up edgeRule (fromNodeType|toNodeType)
+        * @throws AAIException the AAI exception
+        */
+       public static String deriveEdgeRuleKeyForThisEdge( String transId, String fromAppId, TitanTransaction graph,  
+                       TitanEdge tEdge ) throws AAIException{
+
+               TitanVertex fromVtx = tEdge.outVertex();
+               TitanVertex toVtx = tEdge.inVertex();
+               String startNodeType = fromVtx.<String>property("aai-node-type").orElse(null);
+               String targetNodeType = toVtx.<String>property("aai-node-type").orElse(null);
+               String key = startNodeType + "|" + targetNodeType;
+               if( EdgeRules.getInstance().hasEdgeRule(startNodeType, targetNodeType) ){
+                       // We can use the node info in the order they were given
+                       return( key );
+               }
+               else {
+                       key = targetNodeType + "|" + startNodeType;
+                       if( EdgeRules.getInstance().hasEdgeRule(targetNodeType, startNodeType) ){
+                               return( key );
+                       }
+                       else {
+                               // Couldn't find a rule for this edge
+                               throw new AAIException("AAI_6120", "No EdgeRule found for passed nodeTypes: " + startNodeType + ", " 
+                                               + targetNodeType); 
+                       }
+               }
+       }// end of deriveEdgeRuleKeyForThisEdge()
+       
+       
+
+       /**
+        * Save aai edge to db.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param edgeLabel the edge label
+        * @param outV the out V
+        * @param inV the in V
+        * @param propHash the prop hash
+        * @return the titan edge
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       private static TitanEdge saveAaiEdgeToDb(String transId, String fromAppId, TitanTransaction graph, String edgeLabel, 
+                       TitanVertex outV, TitanVertex inV, HashMap <String,Object> propHash) throws AAIException{
+               return  saveAaiEdgeToDb( transId,  fromAppId,  graph,  edgeLabel, 
+                               outV,  inV, propHash, null);
+       }
+       
+       /**
+        * Persist aai edge.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param startVert the start vert
+        * @param targetVert the target vert
+        * @param apiVersion the api version
+        * @return the titan edge
+        * @throws AAIException the AAI exception
+        */
+       public static TitanEdge persistAaiEdge( String transId, String fromAppId, TitanTransaction graph,  
+                       TitanVertex startVert, TitanVertex targetVert, String apiVersion ) throws AAIException{
+               TitanEdge returnEdge = persistAaiEdge(transId, fromAppId, graph, startVert, targetVert, apiVersion, "");
+               return returnEdge;
+       }
+       
+       /**
+        * Persist aai edge.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param startVert the start vert
+        * @param targetVert the target vert
+        * @param apiVersion the api version
+        * @param edgeType the edge type
+        * @return TitanEdge
+        * @throws AAIException the AAI exception
+        */
+       public static TitanEdge persistAaiEdge( String transId, String fromAppId, TitanTransaction graph,  
+                       TitanVertex startVert, TitanVertex targetVert, String apiVersion, String edgeType ) throws AAIException{
+
+               TitanVertex fromVtx = null;
+               TitanVertex toVtx = null;
+               String startNodeType = startVert.<String>property("aai-node-type").orElse(null);
+               String targetNodeType = targetVert.<String>property("aai-node-type").orElse(null);
+               String fwdRuleKey = startNodeType + "|" + targetNodeType;
+               int fwdRuleCount = 0;
+               String fwdRule = "";
+               String fwdLabel = "";
+               String revRuleKey = targetNodeType + "|" + startNodeType;
+               int revRuleCount = 0;   
+               String revRule = "";
+               String revLabel = "";
+               String edRule = "";
+               String edLabel = "";
+               
+               Boolean checkType = false;
+               if( (edgeType != null) && edgeType != "" ){
+                       checkType = true;
+               }
+               
+               // As of 16-07, it is possible to have more than one kind of edge defined between a given 
+               // pair of nodeTypes.   So we need to check to see if there is only one possibility, or if
+               // we need to look at the edgeType to determine which to use.  
+               // NOTE -- we're only supporting having 2 edges between a given pair of nodeTypes and
+               //    one and only one of them would have to be a parent-child edge.
+               
+               if( DbEdgeRules.EdgeRules.containsKey(fwdRuleKey) ){
+                       Collection <String> edRuleColl = DbEdgeRules.EdgeRules.get(fwdRuleKey);
+                       Iterator <String> ruleItr = edRuleColl.iterator();
+                       while( ruleItr.hasNext() ){
+                               String tmpRule = ruleItr.next();
+                               String [] rules = tmpRule.split(",");
+                               String tmpLabel = rules[0];
+                               String tmpParChild = rules[3];
+                               if( !checkType 
+                                               || (checkType && tmpParChild.equals("true") && edgeType.equals("parentChild"))
+                                               || (checkType && tmpParChild.equals("false") && edgeType.equals("cousin"))   ){
+                                       // Either they didn't want us to check the edgeType or it is a match
+                                       fwdRuleCount++;
+                                       if( fwdRuleCount > 1 ){
+                                               // We found more than one with the given info
+                                               throw new AAIException("AAI_6120", "Multiple EdgeRules found for nodeTypes: [" + startNodeType + "], [" 
+                                                               + targetNodeType + "], edgeType = [" + edgeType + "]."); 
+                                       }
+                                       else {
+                                               fwdRule = tmpRule;
+                                               fwdLabel = tmpLabel;
+                                       }
+                               }
+                       }
+               }
+               
+               // Try it the other way also (unless this is the case of a nodeType recursively pointing to itself 
+               // Ie. the edge rule:  "model-element|model-element"
+               if( !revRuleKey.equals(fwdRuleKey) && DbEdgeRules.EdgeRules.containsKey(revRuleKey) ){
+                       Collection <String> edRuleColl = DbEdgeRules.EdgeRules.get(revRuleKey);
+                       Iterator <String> ruleItr = edRuleColl.iterator();
+                       while( ruleItr.hasNext() ){
+                               String tmpRule = ruleItr.next();
+                               String [] rules = tmpRule.split(",");
+                               String tmpLabel = rules[0];
+                               String tmpParChild = rules[3];
+                               if( !checkType 
+                                               || (checkType && tmpParChild.equals("true") && edgeType.equals("parentChild"))
+                                               || (checkType && tmpParChild.equals("false") && edgeType.equals("cousin"))   ){
+                                       // Either they didn't want us to check the edgeType or it is a match
+                                       revRuleCount++;
+                                       if( revRuleCount > 1 ){
+                                               // We found more than one with the given info
+                                               throw new AAIException("AAI_6120", "Multiple EdgeRules found for nodeTypes: [" + targetNodeType + "], [" 
+                                                               + startNodeType + "], edgeType = [" + edgeType + "]."); 
+                                       }
+                                       else {
+                                               revRule = tmpRule;
+                                               revLabel = tmpLabel;
+                                       }
+                               }
+                       }
+               }
+                       
+               if( (fwdRuleCount == 1) && (revRuleCount == 0) ){
+                       // We can use the node info in the order they were given
+                       fromVtx = startVert;
+                       toVtx = targetVert;
+                       edRule = fwdRule;
+                       edLabel = fwdLabel;
+               }
+               else if( (fwdRuleCount == 0) && (revRuleCount == 1) ){
+                       // We need to switch the vertex order so the edge-direction is correct
+                       toVtx = startVert;
+                       fromVtx = targetVert;
+                       edRule = revRule;
+                       edLabel = revLabel;
+               }
+               else if( (fwdRuleCount == 0) && (revRuleCount == 0) ){
+                       // No edge rule found for this
+                       throw new AAIException("AAI_6120", "No EdgeRule found for passed nodeTypes: " + startNodeType + ", " + targetNodeType 
+                                       + "], checkLabelType = [" + edgeType + "]."); 
+               }       
+               else if( (fwdRuleCount > 0) && (revRuleCount > 0) ){
+                       // We found more than one with the given info
+                       throw new AAIException("AAI_6120", "Multiple EdgeRules (fwd and rev) found for nodeTypes: [" + startNodeType + "], [" 
+                                       + targetNodeType + "], checkLabelType = [" + edgeType + "]."); 
+               }
+               
+               // If we got to this point, we now have a single edge label and we know to and from Vtx.
+               
+               HashMap <String,Object> edgeParamHash = getEdgeTagPropPutHash4Rule(transId, fromAppId, edRule);
+               // We do "source-of-truth" for all edges
+               edgeParamHash.put("source-of-truth", fromAppId );
+
+               TitanEdge returnEdge = saveAaiEdgeToDb(transId, fromAppId, graph, edLabel, fromVtx, toVtx, edgeParamHash, apiVersion);
+
+               return returnEdge;
+
+       }
+       
+       /**
+        * Persist aai edge.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param startVert the start vert
+        * @param targetVert the target vert
+        * @return the titan edge
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static TitanEdge persistAaiEdge( String transId, String fromAppId, TitanTransaction graph,  
+                       TitanVertex startVert, TitanVertex targetVert ) throws AAIException{
+               return persistAaiEdge( transId,  fromAppId,  graph,  
+                               startVert,  targetVert, null);
+       }
+       // End persistAaiEdge()
+
+
+       /**
+        * Persist aai edge.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param edgeLabel the edge label
+        * @param startVert the start vert
+        * @param targetVert the target vert
+        * @param propHash the prop hash
+        * @param addIfNotFound the add if not found
+        * @return the titan edge
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static TitanEdge persistAaiEdge( String transId, String fromAppId, TitanTransaction graph,  
+                       String edgeLabel, TitanVertex startVert, TitanVertex targetVert, 
+                       HashMap <String,Object> propHash, Boolean addIfNotFound ) throws AAIException{  
+
+               /*----- This method is depricated ------
+                *  We will ignore the parameters: edgeLabel, propHash and addIfNotFound
+                *  We will use the remaining params to call the newer version of this method
+                */
+               TitanEdge returnEdge = persistAaiEdge(transId, fromAppId, graph, startVert, targetVert, null);
+
+               return returnEdge;
+
+       }// End depricated version of persistAaiEdge()
+
+
+       /**
+        * Persist aai edge with dep params.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param startVert the start vert
+        * @param targetNodeType the target node type
+        * @param targetNodeParamHash the target node param hash
+        * @param apiVersion the api version
+        * @return TitanEdge
+        * @throws AAIException the AAI exception
+        */
+       public static TitanEdge persistAaiEdgeWithDepParams( String transId, String fromAppId, TitanTransaction graph,  
+                       TitanVertex startVert, String targetNodeType, HashMap <String,Object> targetNodeParamHash, String apiVersion) throws AAIException{
+
+               TitanVertex targetVert = getUniqueNodeWithDepParams( transId, fromAppId, graph, targetNodeType, targetNodeParamHash, apiVersion );
+               TitanEdge returnEdge = persistAaiEdge(transId, fromAppId, graph, startVert, targetVert, apiVersion);
+
+               return returnEdge;
+
+       }// End persistAaiEdgeWithDepParams()
+       
+       // Version that lets you pass in an edgeType ("parentChild" or "cousin" since it sometimes cannot be determined 
+       /**
+        * Persist aai edge with dep params.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param startVert the start vert
+        * @param targetNodeType the target node type
+        * @param targetNodeParamHash the target node param hash
+        * @param apiVersion the api version
+        * @param edgeType the edge type
+        * @return the titan edge
+        * @throws AAIException the AAI exception
+        */
+       // from the two nodeTypes anymore (16-07)
+       public static TitanEdge persistAaiEdgeWithDepParams( String transId, String fromAppId, TitanTransaction graph,  
+                       TitanVertex startVert, String targetNodeType, HashMap <String,Object> targetNodeParamHash, 
+                       String apiVersion, String edgeType) throws AAIException{
+               TitanVertex targetVert = getUniqueNodeWithDepParams( transId, fromAppId, graph, targetNodeType, targetNodeParamHash, apiVersion );
+               TitanEdge returnEdge = persistAaiEdge(transId, fromAppId, graph, startVert, targetVert, apiVersion, edgeType);
+
+               return returnEdge;
+
+       }// End persistAaiEdgeWithDepParams()
+       
+       /**
+        * Persist aai edge with dep params.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param startVert the start vert
+        * @param targetNodeType the target node type
+        * @param targetNodeParamHash the target node param hash
+        * @return the titan edge
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static TitanEdge persistAaiEdgeWithDepParams( String transId, String fromAppId, TitanTransaction graph,  
+                       TitanVertex startVert, String targetNodeType, HashMap <String,Object> targetNodeParamHash) throws AAIException{
+               return persistAaiEdgeWithDepParams(  transId,  fromAppId,  graph,  
+                                startVert,  targetNodeType,  targetNodeParamHash, null);
+       }
+
+       /**
+        * Gets the node key prop hash.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param vtx the vtx
+        * @return nodeKeyPropHash
+        * @throws AAIException the AAI exception
+        */
+       public static HashMap <String, Object> getNodeKeyPropHash( String transId, String fromAppId, TitanTransaction graph, TitanVertex vtx) throws AAIException{
+
+               if( vtx == null ){
+                       throw new AAIException("AAI_6109", "null node object passed to getNodeKeyPropHash().");
+               }
+               
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+               String nType = vtx.<String>property("aai-node-type").orElse(null);
+               if( ! dbMaps.NodeKeyProps.containsKey(nType) ){
+                       // Problem if no key Properties defined for this nodeType
+                       String defVer = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP);
+                       throw new AAIException("AAI_6105", "No node-key-properties defined in dbMaps for nodeType = " + nType + " (ver=" + defVer + ")"); 
+               }
+
+               HashMap <String,Object>nodeKeyPropsHash = new HashMap<String,Object>();
+               Collection <String> keyProps =  dbMaps.NodeKeyProps.get(nType);
+               Iterator <String> keyPropI = keyProps.iterator();
+               while( keyPropI.hasNext() ){
+                       String propName = keyPropI.next();
+                       Object value = (Object) vtx.<Object>property(propName).orElse(null); 
+                       nodeKeyPropsHash.put(propName, value);
+               }
+
+               return nodeKeyPropsHash;
+
+       }// End of getNodeKeyPropHash()
+
+       /**
+        * Gets the node name prop hash.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param vtx the vtx
+        * @param apiVersion the api version
+        * @return nodeKeyPropHash
+        * @throws AAIException the AAI exception
+        */
+       public static HashMap <String, Object> getNodeNamePropHash( String transId, String fromAppId, TitanTransaction graph, TitanVertex vtx, String apiVersion) throws AAIException{
+
+               if( vtx == null ){
+                       throw new AAIException("AAI_6109", "null node object passed to getNodeNamePropHash()." );
+               }
+
+               String nType = vtx.<String>property("aai-node-type").orElse(null);
+               HashMap <String,Object>nodeNamePropsHash = new HashMap<String,Object>();
+               Collection <String> keyProps =  DbMeth.getNodeNameProps(transId, fromAppId, nType, apiVersion);
+               Iterator <String> keyPropI = keyProps.iterator();
+               while( keyPropI.hasNext() ){
+                       String propName = keyPropI.next();
+                       Object value = (Object) vtx.<Object>property(propName).orElse(null); 
+                       nodeNamePropsHash.put(propName, value);
+               }
+
+               return nodeNamePropsHash;
+
+       }// End of getNodeNamePropHash()
+       
+
+       /**
+        * Removes the aai edge.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param tEdge the t edge
+        * @return void
+        */
+       public static void removeAaiEdge( String transId, String fromAppId, TitanTransaction graph, TitanEdge tEdge){
+               // Before removing the edge, touch the vertices on each side so their resource-versions will get updated 
+               TitanVertex tmpVIn = tEdge.inVertex();
+               touchVertex( transId, fromAppId, tmpVIn );
+                
+               TitanVertex tmpVOut = tEdge.outVertex();
+               touchVertex( transId, fromAppId, tmpVOut );
+
+               // Remove the passed in edge.
+               tEdge.remove();
+
+       }// end of removeAaiEdge()
+
+
+       /**
+        * Removes the aai node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param thisVtx the this vtx
+        * @param scopeParam the scope param
+        * @param apiVersion the api version
+        * @param resourceVersion the resource version
+        * @throws AAIException the AAI exception
+        */
+       public static void removeAaiNode( String transId, String fromAppId, TitanTransaction graph, TitanVertex thisVtx, String scopeParam, 
+                       String apiVersion, String resourceVersion ) throws AAIException{
+               // Note: the resource Version Override flag is only set to true when called by the Model Delete code which
+               //    has no way to know the resource-versions of nodes at lower-levels of it's model topology.
+               Boolean resVersionOverrideFlag = false;
+               removeAaiNode( transId, fromAppId, graph, thisVtx, scopeParam, apiVersion, resourceVersion, resVersionOverrideFlag );
+       }
+       
+
+       /**
+        *  <pre>
+        *  Possible values for deleteScope can be:
+        *      USE_DEFAULT - Get the scope from ref data for this node
+        *      THIS_NODE_ONLY (but should fail if it there are nodes that depend on it for uniqueness)
+        *      CASCADE_TO_CHILDREN  - will look for OUT-Edges that have parentOf/hasDelTarget = true and follow those down
+        *      ERROR_4_IN_EDGES_OR_CASCADE - combo of error-if-any-IN-edges + CascadeToChildren
+        *      ERROR_IF_ANY_IN_EDGES - Fail if this node has any existing IN edges 
+        *      ERROR_IF_ANY_EDGES - Fail if this node has any existing edges at all!
+        *  </pre>.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param thisVtx the this vtx
+        * @param scopeParam the scope param
+        * @param apiVersion the api version
+        * @param resourceVersion the resource version
+        * @param resVerOverride the res ver override
+        * @return void
+        * @throws AAIException the AAI exception
+        */
+       public static void removeAaiNode( String transId, String fromAppId, TitanTransaction graph, TitanVertex thisVtx, String scopeParam, 
+                       String apiVersion, String resourceVersion, Boolean resVerOverride ) throws AAIException{
+               String nodeType2Del = thisVtx.<String>property("aai-node-type").orElse(null);
+               String deleteScope = scopeParam;
+               if( scopeParam.equals("USE_DEFAULT") ){
+                       deleteScope =   getDefaultDeleteScope(transId, fromAppId, nodeType2Del, apiVersion);
+               }
+               
+               if( !resVerOverride && needToDoResourceVerCheck(apiVersion, false) ){
+                       // Need to check that they knew what they were deleting
+                       String existingResVer = thisVtx.<String>property("resource-version").orElse(null);
+                       if( resourceVersion == null || resourceVersion.equals("") ){
+                               throw new AAIException("AAI_6130", "Resource-version not passed for delete of = " + nodeType2Del); 
+                       }
+                       else if( (existingResVer != null) && !resourceVersion.equals(existingResVer) ){
+                               throw new AAIException("AAI_6131", "Resource-version MISMATCH for delete of = " + nodeType2Del); 
+                       }
+               }
+
+               if( !deleteScope.equals("THIS_NODE_ONLY")
+                               && !deleteScope.equals("CASCADE_TO_CHILDREN")
+                               && !deleteScope.equals("ERROR_4_IN_EDGES_OR_CASCADE")
+                               && !deleteScope.equals("ERROR_IF_ANY_EDGES")
+                               && !deleteScope.equals("ERROR_IF_ANY_IN_EDGES") ){
+                       throw new AAIException("AAI_6120", "Unrecognized value in deleteScope:  [" + deleteScope + "]."); 
+               }
+
+               if( deleteScope.equals("ERROR_IF_ANY_EDGES") ){
+                       if ( thisVtx.edges(Direction.BOTH).hasNext() ) {
+                               throw new AAIException("AAI_6110", "Node cannot be deleted because it still has Edges and the ERROR_IF_ANY_EDGES scope was used."); 
+                       }
+               } 
+               else if( deleteScope.equals("ERROR_IF_ANY_IN_EDGES") || deleteScope.equals("ERROR_4_IN_EDGES_OR_CASCADE") ){
+                       Iterator <Edge> eI = thisVtx.edges(Direction.IN);
+                       boolean onlyHasParent = false;
+                       Edge temp = null;
+                       if( eI != null && eI.hasNext() ){
+                               temp = eI.next();
+                               Boolean isParent = temp.<Boolean>property("isParent").orElse(null);
+                               if (isParent != null && isParent && !eI.hasNext()) {
+                                       onlyHasParent = true;
+                               }
+                               
+                               if (!onlyHasParent) {
+                                       throw new AAIException("AAI_6110", "Node cannot be deleted because it still has Edges and the " + deleteScope + " scope was used.");
+                               }
+                       }
+               }
+               else if( deleteScope.equals("THIS_NODE_ONLY")){
+                       // Make sure nobody depends on this node.
+                       Iterator<Edge> eI = thisVtx.edges(Direction.BOTH);
+                       while( eI.hasNext() ){
+                               TitanEdge ed = (TitanEdge) eI.next();
+                               TitanVertex otherVtx = (TitanVertex) ed.otherVertex(thisVtx);
+                               String nodeTypeA = otherVtx.<String>property("aai-node-type").orElse(null);
+                               if( nodeTypeACanDependOnB(transId, fromAppId, nodeTypeA, nodeType2Del, apiVersion)){
+                                       // We're only supposed to delete this node - but another node is dependant on it,
+                                       // so we shouldn't delete this one.
+                                       throw new AAIException("AAI_6110", "Node cannot be deleted using scope = " + deleteScope + 
+                                                       " another node (type = " + nodeTypeA + ") depends on it for uniqueness."); 
+                               }
+                       }
+               }
+
+               // We've passed our checks - so do some deleting of edges and maybe pass 
+               //     the delete request down to children or delete-targets.
+
+               // First we deal with the "IN"-Edges which can't have children/delete-targets which
+               // by definition (of "IN") on the other end
+               Iterator <Edge> eI_In = thisVtx.edges(Direction.IN);
+               while( eI_In.hasNext() ){
+                       TitanEdge ed = (TitanEdge) eI_In.next();
+                       
+                       //- "touch" vertex on other side of this edge so it gets a fresh resource-version
+                       TitanVertex tmpVOther = ed.otherVertex(thisVtx);
+                       touchVertex( transId, fromAppId, tmpVOther );
+                       
+                       ed.remove();
+               }
+
+               // Now look at the "OUT"-edges which might include children or delete-targets
+               String cascadeMsg = "This nt = " + nodeType2Del + ", Cascading del to: ";
+               Iterator <Edge> eI_Out = thisVtx.edges(Direction.OUT);
+               if( !eI_Out.hasNext() ){
+                       cascadeMsg = cascadeMsg + "[no children for this node]";
+               }
+               while( eI_Out.hasNext() ){
+                       TitanEdge ed = (TitanEdge) eI_Out.next();
+                       
+                       // "touch" vertex on other side of this edge so it gets a fresh resource-version
+                       TitanVertex tmpVOther = ed.otherVertex(thisVtx);
+                       touchVertex( transId, fromAppId, tmpVOther );
+
+                       Boolean otherVtxAChild = ed.<Boolean>property("isParent").orElse(null);
+                       if( otherVtxAChild == null ){
+                               otherVtxAChild = false;
+                       }
+
+                       Boolean otherVtxADeleteTarget = ed.<Boolean>property("hasDelTarget").orElse(null);
+                       if( otherVtxADeleteTarget == null ){
+                               otherVtxADeleteTarget = false;
+                       }
+
+                       if( (otherVtxAChild || otherVtxADeleteTarget) && 
+                                       (deleteScope.equals("CASCADE_TO_CHILDREN") || deleteScope.equals("ERROR_4_IN_EDGES_OR_CASCADE")) ){
+                               // Delete the edge to the child and Pass the delete down to it.
+                               ed.remove();
+                               TitanVertex otherVtx = (TitanVertex) ed.otherVertex(thisVtx);
+                               String vid = otherVtx.id().toString();
+                               String nty = otherVtx.<String>property("aai-node-type").orElse(null);
+                               String resVers = otherVtx.<String>property("resource-version").orElse(null);
+                               cascadeMsg = cascadeMsg + "[" + nty + ":" + vid + "]";
+                               removeAaiNode(transId, fromAppId, graph, otherVtx, "CASCADE_TO_CHILDREN", apiVersion, resVers);
+                       }
+                       else {
+                               // The other node is not a child or deleteTarget.  Delete the edge to it if it is not
+                               // dependent (Should never be dependent since it's not a child/delTarget...  but 
+                               // someone could create a node that was dependent for Uniqueness without
+                               // being a child/target.
+
+                               // DEBUG -- eventually add the check for dependancy that isn't on a parent-type or delTarget-type edge
+                               ed.remove();
+                       }
+               }
+               
+               LOGGER.info(cascadeMsg);
+
+               Iterator<Edge> eI = thisVtx.edges(Direction.BOTH);
+               if( ! eI.hasNext() ){
+                       // By this point, either there were no edges to deal with, or we have dealt with them.
+                       thisVtx.remove();
+               }
+               else {
+                       // Something went wrong and we couldn't delete all the edges for this guy.
+                       throw new AAIException("AAI_6110", "Node could be deleted because it unexpectedly still has Edges.\n"); 
+               }
+       }
+       
+       
+       /**
+        * Removes the aai node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param thisVtx the this vtx
+        * @param scopeParam the scope param
+        * @return void
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static void removeAaiNode( String transId, String fromAppId, TitanTransaction graph, TitanVertex thisVtx, String scopeParam) throws AAIException{
+               removeAaiNode(transId, fromAppId, graph, thisVtx, scopeParam, null, null);
+       }
+       
+       /**
+        * Removes the aai node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param thisVtx the this vtx
+        * @param scopeParam the scope param
+        * @param apiVersion the api version
+        * @throws AAIException the AAI exception
+        */
+       @Deprecated
+       public static void removeAaiNode( String transId, String fromAppId, TitanTransaction graph, TitanVertex thisVtx, String scopeParam, 
+                       String apiVersion ) throws AAIException{
+               removeAaiNode(transId, fromAppId, graph, thisVtx, scopeParam, apiVersion, null);
+       }
+       // end of removeAaiNode()
+
+
+       /**
+        * Delete all graph data.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @return void
+        */
+       public static void deleteAllGraphData( String transId, String fromAppId, TitanGraph graph ){
+               /** ======================================================================
+                * WARNING -- this removes ALL the data that is currently in the graph.
+                * ======================================================================
+                **/
+                LOGGER.warn("deleteAllGraphData called! Run for the hills!");
+               Iterator<Edge> edges = graph.edges(Direction.BOTH);
+               graph.tx().commit();
+               Edge edge = null;
+               while (edges.hasNext()) {
+                       edge = edges.next();
+                       edges.remove();
+               }
+               graph.tx().commit();
+               Iterator<Vertex> vertices = graph.vertices();
+               graph.tx().commit();
+               Vertex vertex = null;
+               while (vertices.hasNext()) {
+                       vertex = vertices.next();
+                       vertex.remove();
+               }
+               graph.tx().commit();
+       }
+
+
+       /**
+        * Show all edges for node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param tVert the t vert
+        * @return the array list
+        */
+       public static ArrayList <String> showAllEdgesForNode( String transId, String fromAppId, TitanVertex tVert ){ 
+
+               ArrayList <String> retArr = new ArrayList <String> ();
+               Iterator <Edge> eI = tVert.edges(Direction.IN);
+               if( ! eI.hasNext() ){
+                       retArr.add("No IN edges were found for this vertex. ");
+               }
+               while( eI.hasNext() ){
+                       TitanEdge ed = (TitanEdge) eI.next();
+                       String lab = ed.label();
+                       TitanVertex vtx = (TitanVertex) ed.otherVertex(tVert);
+                       if( vtx == null ){
+                               retArr.add(" >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = " + ed.id() + " <<< ");
+                       }
+                       else {
+                               String nType = vtx.<String>property("aai-node-type").orElse(null);
+                               String vid = vtx.id().toString();
+                               retArr.add("Found an IN edge (" + lab + ") to this vertex from a [" + nType + "] node with VtxId = " + vid );
+                               //DEBUG ---
+                               //showPropertiesForEdge(  transId, fromAppId, ed );
+                       }
+               }
+               
+               eI = tVert.edges(Direction.OUT);
+               if( ! eI.hasNext() ){
+                       retArr.add("No OUT edges were found for this vertex. ");
+               }
+               while( eI.hasNext() ){
+                       TitanEdge ed = (TitanEdge) eI.next();
+                       String lab = ed.label();
+                       TitanVertex vtx = (TitanVertex) ed.otherVertex(tVert);
+                       if( vtx == null ){
+                               retArr.add(" >>> COULD NOT FIND VERTEX on the other side of this edge edgeId = " + ed.id() + " <<< ");
+                       }
+                       else {
+                               String nType = vtx.<String>property("aai-node-type").orElse(null);
+                               String vid = vtx.id().toString();
+                               retArr.add("Found an OUT edge (" + lab + ") from this vertex to a [" + nType + "] node with VtxId = " + vid );
+                               //DEBUG ---
+                               //showPropertiesForEdge(  transId, fromAppId, ed );
+                       }
+               }
+               return retArr;
+       }
+
+       
+       /**
+        * Show properties for node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param tVert the t vert
+        * @return the array list
+        */
+       public static ArrayList <String> showPropertiesForNode( String transId, String fromAppId, TitanVertex tVert ){ 
+
+               ArrayList <String> retArr = new ArrayList <String> ();
+               if( tVert == null ){
+                       retArr.add("null Node object passed to showPropertiesForNode()\n");
+               }
+               else {
+                       String nodeType = "";
+                       //String datType = "";
+                       Object ob = tVert.<Object>property("aai-node-type").orElse(null);
+                       if( ob == null ){
+                               nodeType = "null";
+                       }
+                       else{
+                               nodeType = ob.toString();
+                               //datType = ob.getClass().getSimpleName();
+                       }
+                       
+                       retArr.add(" AAINodeType/VtxID for this Node = [" + nodeType + "/" + tVert.id() + "]");
+                       retArr.add(" Property Detail: ");
+                       Iterator<VertexProperty<Object>> pI = tVert.properties();
+                       while( pI.hasNext() ){
+                               VertexProperty<Object> tp = pI.next();
+                               Object val = tp.value();
+                               //retArr.add("Prop: [" + tp.getPropertyKey() + "], val = [" + val + "], dataType = " + val.getClass() );
+                               retArr.add("Prop: [" + tp.key() + "], val = [" + val + "] ");
+                       }
+               }
+               return retArr;
+       }
+
+       
+       /**
+        * Gets the node name props.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the node type
+        * @param apiVersion the api version
+        * @return HashMap of keyProperties
+        * @throws AAIException the AAI exception
+        */
+       public static Collection <String> getNodeNameProps( String transId, String fromAppId, String nodeType, String apiVersion ) throws AAIException{
+
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+               Collection <String> nameProps = new ArrayList <String>();
+               if( dbMaps.NodeNameProps.containsKey(nodeType) ){
+                       nameProps = dbMaps.NodeNameProps.get(nodeType);
+               }
+               else if( DbEdgeRules.NodeTypeCategory.containsKey(nodeType) ){
+                       // The passed-in nodeType was really a nodeCategory, theoretically, all the guys in the same 
+                       // category should have the same name property -- so if they just give us the category, we will
+                       // just give the name info from the first nodeType we encounter of that category.
+                       Collection <String> nTypeCatCol = DbEdgeRules.NodeTypeCategory.get(nodeType);
+                       Iterator <String> catItr = nTypeCatCol.iterator();
+                       String catInfo = "";
+                       if( catItr.hasNext() ){
+                               // For now, we only look for one.
+                               catInfo = catItr.next();
+                       }
+                       else {
+                               throw new AAIException("AAI_6105", "Required Property name(s) not found for nodeType = " + nodeType); 
+                       }
+
+                       String [] flds = catInfo.split(",");
+                       if( flds.length != 4 ){
+                               throw new AAIException("AAI_6121", "Bad EdgeRule.NodeTypeCategory data (itemCount=" + flds.length + ") for nodeType = [" + nodeType + "]."); 
+                       }
+
+                       String nodeTypesString = flds[0];
+                       String [] nodeTypeNames = nodeTypesString.split("\\|");
+                       if( nodeTypeNames != null && nodeTypeNames.length > 0 ){
+                               // We'll just use the first one
+                               String nt = nodeTypeNames[0];
+                               nameProps = dbMaps.NodeNameProps.get(nt);
+                       }
+               }
+               
+               
+               // Note - it's ok if there was no defined name property for this nodeType.
+               
+               return nameProps;
+
+       }// end of getNodeKeyPropNames
+       
+       
+       /**
+        * Gets the edge tag prop put hash 4 rule.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param edRule the ed rule
+        * @return the edge tag prop put hash 4 rule
+        * @throws AAIException the AAI exception
+        */
+       public static HashMap <String,Object> getEdgeTagPropPutHash4Rule( String transId, String fromAppId, String edRule ) 
+                       throws AAIException{ 
+               // For a given edgeRule - already pulled out of DbEdgeRules.EdgeRules --  parse out the "tags" that 
+               //     need to be set for this kind of edge.  
+               // These are the Boolean properties like, "isParent", "usesResource" etc.  
+               HashMap <String,Object> retEdgePropPutMap = new HashMap <String,Object>();
+               
+               if( (edRule == null) || edRule.equals("") ){
+                       // No edge rule found for this
+                       throw new AAIException("AAI_6120", "blank edRule passed to getEdgeTagPropPutHash4Rule()"); 
+               }
+                       
+               int tagCount = DbEdgeRules.EdgeInfoMap.size();
+               String [] rules = edRule.split(",");
+               if( rules.length != tagCount ){
+                       throw new AAIException("AAI_6121", "Bad EdgeRule data (itemCount =" + rules.length + ") for rule = [" + edRule  + "]."); 
+               }
+
+               // In DbEdgeRules.EdgeRules -- What we have as "edRule" is a comma-delimited set of strings.
+               // The first item is the edgeLabel.
+               // The second in the list is always "direction" which is always OUT for the way we've implemented it.
+               // Items starting at "firstTagIndex" and up are all assumed to be booleans that map according to 
+               // tags as defined in EdgeInfoMap.
+               // Note - if they are tagged as 'reverse', that means they get the tag name with "-REV" on it
+               for( int i = DbEdgeRules.firstTagIndex; i < tagCount; i++ ){
+                       String booleanStr = rules[i];
+                       Integer mapKey = new Integer(i);
+                       String propName = DbEdgeRules.EdgeInfoMap.get(mapKey);
+                       String revPropName = propName + "-REV";
+                       
+                       if( booleanStr.equals("true") ){
+                               retEdgePropPutMap.put(propName, true);
+                               retEdgePropPutMap.put(revPropName,false);
+                       }
+                       else if( booleanStr.equals("false") ){
+                               retEdgePropPutMap.put(propName, false);
+                               retEdgePropPutMap.put(revPropName,false);
+                       }
+                       else if( booleanStr.equals("reverse") ){
+                               retEdgePropPutMap.put(propName, false);
+                               retEdgePropPutMap.put(revPropName,true);
+                       }
+                       else {
+                               throw new AAIException("AAI_6121", "Bad EdgeRule data for rule = [" + edRule + "], val = [" + booleanStr + "]."); 
+                       }
+                       
+               }
+
+               return retEdgePropPutMap;
+               
+       } // End of getEdgeTagPropPutHash()
+
+
+       
+       /**
+        * Gets the edge tag prop put hash.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param edgeRuleKey the edge rule key
+        * @return the edge tag prop put hash
+        * @throws AAIException the AAI exception
+        */
+       public static Map<String, EdgeRule> getEdgeTagPropPutHash( String transId, String fromAppId, String edgeRuleKey ) 
+                       throws AAIException{ 
+               // For a given edgeRuleKey (nodeTypeA|nodeTypeB), look up the rule that goes with it in
+               // DbEdgeRules.EdgeRules and parse out the "tags" that need to be set on each edge.  
+               // These are the Boolean properties like, "isParent", "usesResource" etc.  
+               // Note - this code is also used by the updateEdgeTags.java code
+
+               String[] edgeRuleKeys = edgeRuleKey.split("\\|");
+               
+               if (edgeRuleKeys.length < 2 || ! EdgeRules.getInstance().hasEdgeRule(edgeRuleKeys[0], edgeRuleKeys[1])) {
+                       throw new AAIException("AAI_6120", "Could not find an DbEdgeRule entry for passed edgeRuleKey (nodeTypeA|nodeTypeB): " + edgeRuleKey + "."); 
+               }
+               
+               Map<String, EdgeRule> edgeRules = EdgeRules.getInstance().getEdgeRules(edgeRuleKeys[0], edgeRuleKeys[1]);
+               
+               return edgeRules;
+               
+       } // End of getEdgeTagPropPutHash()
+
+       
+       /**
+        * This property was put by newer version of code.
+        *
+        * @param apiVersionStr the api version str
+        * @param nodeType the node type
+        * @param propName the prop name
+        * @return true, if successful
+        * @throws AAIException the AAI exception
+        */
+       private static boolean  thisPropertyWasPutByNewerVersionOfCode( String apiVersionStr, 
+                                       String nodeType, String propName) throws AAIException{
+               // We want to return True if the nodeType + property-name combo was introduced AFTER the apiVersion passed.
+               
+               int apiVerInt = 0;
+               int propIntroVerInt = 0;
+               
+               if( apiVersionStr == null || apiVersionStr.equals("") ){
+                       apiVersionStr = org.openecomp.aai.util.AAIApiVersion.get();
+               }
+               apiVerInt = getVerNumFromVerString(apiVersionStr);
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               String propIntroKey = nodeType + "|" + propName;
+               if( propName.equals("prov-status") ){
+                       // This is a special case -- The dbMaps from v2 has it in there, but it was introduced half way through.  So
+                       // it needs to be catogorized as v3.
+                       propIntroVerInt = 3;
+               }
+               else if( ! dbMaps.PropertyVersionInfoMap.containsKey(propIntroKey) ){
+                       String detail = propIntroKey + " [" + propIntroKey + "] not found in dbMaps.PropertyVersionInfoMap."; 
+                       throw new AAIException("AAI_6121", detail); 
+               }
+               else {
+                       String propIntroVerString = dbMaps.PropertyVersionInfoMap.get(propIntroKey);
+                       propIntroVerInt = getVerNumFromVerString( propIntroVerString );
+               }
+               
+               if( propIntroVerInt > apiVerInt ){
+                       return true;
+               }
+               else {
+                       return false;
+               }
+               
+       } // End of thisPropertyWasPutByNewerVersionOfCode()
+
+       
+       /**
+        * Touch vertex.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param v the v
+        * @return void
+        */
+       public static void touchVertex( String transId, String fromAppId, TitanVertex v ){
+               // We want to "touch" the vertex -- Ie. update it's last-mod-date, last-mod- resource-version to the current date/time
+               if( v != null ){
+                       long unixTimeNow = System.currentTimeMillis() / 1000L;
+                       String timeNowInSec = "" + unixTimeNow;
+                       v.property( "aai-last-mod-ts", timeNowInSec );
+                       v.property( "resource-version", timeNowInSec );
+                       v.property( "last-mod-source-of-truth", fromAppId );
+               }
+       } // End of touchVertex()
+       
+       
+       /**
+        * Check prop cardinality.
+        *
+        * @param propName the prop name
+        * @param cardinalityType the cardinality type
+        * @return boolean
+        * @throws AAIException the AAI exception
+        */
+       public static boolean checkPropCardinality( String propName, String cardinalityType ) throws AAIException {
+               
+               // Return true if the named property is tagged in our dbMaps PropetyDataTypeMap as 
+               // having the passed in cardinality type.  
+               // NOTE: supported cardinality types in dbMaps = "Set" or "List"
+               // In Titan (and ex5.json), those go in as "SET" and "LIST"
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+               if( dbMaps.PropertyDataTypeMap.containsKey(propName) ){
+                       String propDataType = dbMaps.PropertyDataTypeMap.get(propName);
+                       if( propDataType != null && propDataType.startsWith(cardinalityType) ){
+                               return true;
+                       }
+               }
+               return false;
+               
+       } // End of checkPropCardinality()
+       
+       /**
+        * Convert type if needed.
+        *
+        * @param propName the prop name
+        * @param val the val
+        * @return convertedValue (if it was a String but needed to be a Boolean)
+        * @throws AAIException the AAI exception
+        */
+       public static Object convertTypeIfNeeded( String propName, Object val )
+                       throws AAIException {
+               // Make sure the dataType of the passed-in Object matches what the DB expects
+               
+               // NOTE: since this is a fix very late in our dev cycle, we'll just fix the scenarios that
+               //   we're having trouble with which is Strings getting into the db which should be going in as 
+               //   Booleans or Integers.
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+               if( dbMaps.PropertyDataTypeMap.containsKey(propName) ){
+                       String dbExpectedDataType = dbMaps.PropertyDataTypeMap.get(propName);
+                       if( dbExpectedDataType != null 
+                                       && dbExpectedDataType.equals("Boolean") 
+                                       && val != null
+                                       && !(val instanceof Boolean) ){
+                               String valStr = val.toString().trim();
+                               if( valStr.equals("true") || valStr.equals("True") || valStr.equals("TRUE") ){
+                                       return Boolean.valueOf("true");
+                               }
+                               else if( valStr.equals("false") || valStr.equals("False") || valStr.equals("FALSE") ){
+                                       return Boolean.valueOf("false");
+                               }
+                               else {
+                                       String emsg = "Error trying to convert value: [" + valStr + "] to a Boolean for property + " + propName + "\n";
+                                       throw new AAIException("AAI_6120", emsg); 
+                               }
+                       }
+                       else if( dbExpectedDataType != null 
+                                       && dbExpectedDataType.equals("Integer") 
+                                       && val != null 
+                                       && !(val.toString().trim().equals("")) 
+                                       && !(val instanceof Integer) ){
+                               String valStr = val.toString().trim();
+                               Integer newInt;
+                               try {
+                                       newInt = Integer.valueOf(valStr);
+                                       return newInt;
+                               }
+                               catch( Exception e ){
+                                       String emsg = "Error trying to convert value: [" + valStr + "] to an Integer for property + " + propName + "\n";
+                                       throw new AAIException("AAI_6120", emsg); 
+                               }
+                       }
+               }
+               
+               // If it didn't need to be converted, just return it.
+               return val;
+       
+       } // End of convertTypeIfNeeded()
+
+       
+       
+       /**
+        * This vertex not reachable.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param v the v
+        * @param version the version
+        * @return boolean
+        */
+       public static boolean thisVertexNotReachable( String transId, String fromAppId, TitanTransaction graph, TitanVertex v, String version){
+               if( v == null ){
+                       return true;   
+               }
+               else {
+                       try {
+                                v.id().toString();
+                       }
+                       catch( Exception ex ){
+                               // Could not get this -- sometimes we're holding a vertex object that has gotten deleted, so
+                               // when we try to get stuff from it, we get an "Element Has Been Removed" error from Titan
+                               return true;
+                       }
+               }
+               
+               return false;
+               
+       } // End of thisVertexNotReachable()
+
+       /**
+        * This vertex has bad edges.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param v the v
+        * @param version the version
+        * @return boolean
+        */
+       public static boolean thisVertexHasBadEdges( String transId, String fromAppId, TitanTransaction graph, TitanVertex v, String version){
+               
+               Iterator <Edge> eItor = v.edges(Direction.BOTH);
+               while( eItor.hasNext() ){
+                       Edge e = null;
+                       e = eItor.next();
+                       if( e == null ){
+                               return true;
+                       }
+                       Vertex vIn = e.inVertex();
+                       if( (vIn == null) || (vIn.<String>property("aai-node-type").orElse(null) == null) ){
+                                // this is a bad edge because it points to a vertex that isn't there anymore
+                                return true;
+                       }
+                       
+                       Vertex vOut = e.outVertex();
+                       if( (vOut == null) || (vOut.<String>property("aai-node-type").orElse(null) == null) ){
+                                // this is a bad edge because it points to a vertex that isn't there anymore
+                                return true;
+                       }
+               }
+               
+               // If we made it to here, the vertex's edges must be ok.
+               return false;
+               
+       } // End of thisVertexHasBadEdges()
+       
+       
+       /**
+        * This vertex is A phantom.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param v the v
+        * @param version the version
+        * @return boolean
+        * @throws AAIException the AAI exception
+        */
+       public static boolean thisVertexIsAPhantom( String transId, String fromAppId, TitanTransaction graph, TitanVertex v, String version ) 
+                       throws AAIException {
+               
+               
+               // The kind of Phantom we're looking for is the kind that we sometimes get when we do a select without
+               // using key properties.  They can be in the database as a vertex, but the indexes that should point to 
+               // them are not working -- so they cannot be used by normal interfaces (like the REST API) which means
+               // that if we return it, it can mess up a caller who tries to use it.
+               if( v == null ){
+                       return true;   
+               }
+               String thisVid =  v.id().toString();
+               
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+               Object propOb = v.<Object>property("aai-node-type").orElse(null);
+               if( propOb == null ){
+                       // This vertex does not have an aai-node-type ---> it is messed up
+                       return true;
+               }
+               String nType = propOb.toString();
+               if(  ! dbMaps.NodeKeyProps.containsKey(nType) ){
+                       // This node Type does not have keys defined
+                       // This could just be bad reference data, so we will not flag this guy, but we
+                       // can't really do our test...
+                       return false;
+               }
+               
+               HashMap <String,Object> propHashWithKeys = new HashMap<String, Object>();
+               Collection <String> keyProps = null;
+               try {
+                       keyProps = getNodeKeyPropNames(transId, fromAppId, nType, version);
+               }
+               catch (AAIException ex) {
+                       // something wrong with getting this guy's key property names - we'll abandon this test...
+                       return false;
+               }
+       
+        Iterator <String> keyPropI = keyProps.iterator();
+        while( keyPropI.hasNext() ){
+               String propName = keyPropI.next();
+               String propVal = "";
+               Object ob = v.<Object>property(propName).orElse(null);
+               if( ob != null ){
+                       propVal = ob.toString();
+               }
+               propHashWithKeys.put(propName, propVal);
+        }
+        try {
+               // Note - We can get more than one back since some nodes need a dep. node for uniqueness.
+               //   We don't care about that -- we just want to make sure we can get this vertex back when
+               //   we're searching with it's indexed fields. 
+               // NOTE - we're passing the skipGroomCheck to getNodes so we don't wind up in an infinite loop
+               ArrayList <TitanVertex> vertList2 = getNodes( transId, fromAppId, graph, nType, propHashWithKeys, false, version, true ); 
+               Iterator<TitanVertex> iter2 = vertList2.iterator(); 
+            while( iter2.hasNext() ){ 
+               TitanVertex tvx2 = iter2.next(); 
+               String foundId = tvx2.id().toString();
+               if( foundId.equals( thisVid ) ){
+                       // We could get back the vertex by looking it up using key properties...  That's good.
+                       return false;
+               }
+            }
+        }
+        catch (Exception e2) {
+                       //String msg = " Error encountered for this vertex id: [" + thisVid + 
+                       //              "]. Caught this exception: " + e2.toString();
+                       // Something messed up - but that doesn't prove that this is a phantom.
+                       return false;
+               }
+               
+        // If we dropped down to here, we have looked but could not pull the vertex out of the
+        //    db using it's key fields, so it gets flagged as a Phantom.
+               return true;
+       
+       } // End of thisVertexIsAPhantom()
+       
+       
+       /**
+        * Gets the node by unique key.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param graph the graph
+        * @param aaiUniquekey the aai uniquekey
+        * @return the node by unique key
+        */
+       public TitanVertex getNodeByUniqueKey(String transId, String fromAppId, TitanTransaction graph, String aaiUniquekey) {
+               
+               TitanVertex vert = null;
+               
+               Iterator<?> vertI =  graph.query().has("aai-unique-key", aaiUniquekey).vertices().iterator(); 
+                                               
+               if( vertI != null && vertI.hasNext()) {
+                       // We found a vertex that meets the input criteria. 
+                       vert = (TitanVertex) vertI.next();
+               }
+               
+               return vert;
+       }
+
+
+
+}
+
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/ModelBasedProcessing.java b/aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/ModelBasedProcessing.java
new file mode 100644 (file)
index 0000000..f51e67b
--- /dev/null
@@ -0,0 +1,3718 @@
+/*-
+ * ============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.dbgraphgen;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+
+import org.openecomp.aai.db.DbMethHelper;
+import org.openecomp.aai.db.props.AAIProperties;
+import org.openecomp.aai.dbgen.PropertyLimitDesc;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.ingestModel.DbMaps;
+import org.openecomp.aai.ingestModel.IngestModelMoxyOxm;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.openecomp.aai.query.builder.QueryBuilder;
+import org.openecomp.aai.serialization.db.DBSerializer;
+import org.openecomp.aai.serialization.db.EdgeRules;
+import org.openecomp.aai.serialization.db.EdgeType;
+import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.SimpleTimeLimiter;
+import com.google.common.util.concurrent.TimeLimiter;
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+/**
+ * Utility class that uses Model/Named-Query definitions to navigate the graph.   
+ */
+public class ModelBasedProcessing{
+
+       private EELFLogger LOGGER = EELFManager.getInstance().getLogger(ModelBasedProcessing.class);
+       private final int MAX_LEVELS = 50;  // max depth allowed for our model - to protect against infinite loop problems
+
+       private TransactionalGraphEngine engine;
+       private Loader loader;
+       private DBSerializer serializer;
+       private DbMethHelper dbMethHelper;
+       
+       protected ModelBasedProcessing() {
+               
+       }
+       public ModelBasedProcessing(Loader loader, TransactionalGraphEngine engine, DBSerializer serializer) {
+               this.loader = loader;
+               this.engine = engine;
+               this.serializer = serializer;
+               dbMethHelper = new DbMethHelper(loader, engine);
+       }
+       /**
+        * Gets the start nodes and model-ver's.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param passedModelVersionId the passed model-version-id -- optional (unique id for a model-ver)
+        * @param passedModelId the passed model-invariant-id -- optional
+        * @param passedModelName the passed model-name -- optional
+        * @param passedTopNodeType the passed top node type -- optional (needed if neither model=invariant-id nor model-version-id is passed)
+        * @param startNodeFilterArrayOfHashes the start node filter array of hashes -- optional (used to locate the first node(s) of instance data)
+        * @param apiVer the api ver
+        * @return HashMap of startNodes and their corresponding model-version-id's
+        * @throws AAIException the AAI exception
+        */
+       public Map<String,String> getStartNodesAndModVersionIds( String transId, String fromAppId,
+                       String passedModelVersionId, 
+                       String passedModelInvId,
+                       String passedModelName,
+                       String passedTopNodeType,
+                       List<Map<String,Object>> startNodeFilterArrayOfHashes, 
+                       String apiVer ) 
+                                       throws AAIException{
+               // ----------------------------------------------------------------------------------------------------
+               // Get a hash for all start-nodes (key = vtxId, val = modelVersionId that applies)
+               //     If no start-node-key info is passed, then use either the passed modelVersion or 
+               //         the passed model-invariant-id or model-name to collect them.
+               //     If start-node-key info is given, use it instead to look for start-nodes. 
+               //         Note: if ONLY start-node-key info is given, then it would have to map to nodes which 
+               //         have persona data.  Otherwise we'd have no way to know what model to collect data with.
+               // ----------------------------------------------------------------------------------------------------
+
+               Iterator<Vertex> startVerts = null;
+               Map<String, String> startVertInfo = new HashMap<>();
+               
+               if( startNodeFilterArrayOfHashes.isEmpty() ){
+                       // Since they did not give any data to find start instances, we will have to find them
+                       // using whatever model-info they provided so we can use it to map to persona-data in the db.
+                       if( (passedModelVersionId == null || passedModelVersionId.equals(""))
+                                        && (passedModelInvId == null || passedModelInvId.equals(""))
+                                        && (passedModelName == null || passedModelName.equals(""))){
+                               throw new AAIException("AAI_6118", "ModelInvariantId or ModelName or ModelVersionId required if no startNodeFilter data passed."); 
+                       }
+                       else {
+                               // Use whatever model info they pass to find start-node instances
+                               // Get the first/top named-query-element used by this query
+                               if( passedModelVersionId != null && !passedModelVersionId.equals("") ){
+                                       // Need to look up the model-invariant-id and model-version to check against persona data
+                                       Vertex modVerVtx = getNodeUsingUniqueId(transId, fromAppId, "model-ver", 
+                                                       "model-version-id", passedModelVersionId);
+                                       Vertex modVtx = getModelGivenModelVer( modVerVtx, "" );
+                                       String calcModId = modVtx.<String>property("model-invariant-id").orElse(null);
+                                       // Now we can look up instances that match this model's info
+                                       if( calcModId != null ){
+                                               startVerts = this.engine.asAdmin().getReadOnlyTraversalSource().V().has("model-invariant-id-local",calcModId).has("model-version-id-local",passedModelVersionId);
+                                       }
+                               }       
+                               else if( passedModelInvId != null && !passedModelInvId.equals("") ){
+                                       // They gave us the model-invariant-id
+                                       startVerts = this.engine.asAdmin().getReadOnlyTraversalSource().V().has("model-invariant-id-local",passedModelInvId);
+                               }
+                               else if( passedModelName != null && !passedModelName.equals("") ){
+                                       List<Vertex> modelVerVtxList = getModelVersUsingName(transId, fromAppId, passedModelName);
+                                       List<Vertex> startVtxList = new ArrayList<>();
+                                       // Need to look up the model-inv-ids and model-versions to check against persona data
+                                       if( !modelVerVtxList.isEmpty() ){
+                                               for( int i = 0; i < modelVerVtxList.size(); i++ ){
+                                                       String calcModVerId = (modelVerVtxList.get(i)).<String>property("model-version-id").orElse(null);
+                                                       Vertex modVtx = getModelGivenModelVer(modelVerVtxList.get(i),"");
+                                                       String calcModInvId = modVtx.<String>property("model-invariant-id").orElse(null);               
+                                                       // Now we can look up instances that match this model's info
+                                                       Iterator<Vertex> tmpStartIter = this.engine.asAdmin().getReadOnlyTraversalSource().V().has("model-invariant-id-local",calcModInvId).has("model-version-id-local",calcModVerId);
+                                                       while( tmpStartIter.hasNext() ){
+                                                               Vertex tmpStartVert = (Vertex) tmpStartIter.next();
+                                                               startVtxList.add(tmpStartVert);
+                                                       }
+                                               }
+                                       }
+                                       if( !startVtxList.isEmpty() ){
+                                               startVerts = startVtxList.iterator();
+                                       }
+                               }       
+                       }
+                       
+                       if( startVerts != null ){ 
+                               while( startVerts.hasNext() ){
+                                       Vertex tmpStartVert = (Vertex) startVerts.next();
+                                       String vid = tmpStartVert.id().toString();
+                                       String tmpModId =  tmpStartVert.<String>property("model-invariant-id-local").orElse(null);
+                                       String tmpModVerId =  tmpStartVert.<String>property("model-version-id-local").orElse(null);
+                                       startVertInfo.put(vid, tmpModVerId);
+                               }
+                       }
+                       if( startVertInfo.isEmpty() ){
+                               throw new AAIException("AAI_6114", "Start Node(s) could not be found for model data passed.  " +
+                                               "(modelVersionId = [" + passedModelVersionId + 
+                                               "], modelInvariantId = [" + passedModelInvId +
+                                               "], modelName = [" + passedModelName +
+                                               "])");
+                       }
+                       
+                       return startVertInfo;
+               }
+               else {
+                       // Use start-node filter info to find start-node(s) - Note - there could also be model info passed that we'll need
+                       //     to use to trim down the set of start-nodes that we find based on the startNodeFilter data.
+                       String modTopNodeType ="";
+                       String modInfoStr = "";
+                       if( passedModelVersionId != null && !passedModelVersionId.equals("") ){
+                               modTopNodeType = getModelVerTopWidgetType( transId, fromAppId, passedModelVersionId, "", "" );
+                               modInfoStr = "modelVersionId = (" + passedModelVersionId + ")"; 
+                       }
+                       else if( passedModelInvId != null && !passedModelInvId.equals("") ){
+                               modTopNodeType = getModelVerTopWidgetType( transId, fromAppId,"", passedModelInvId, "" );
+                               modInfoStr = "modelId = (" + passedModelInvId + ")"; 
+                       }
+                       else if( passedModelName != null && !passedModelName.equals("") ){
+                               modTopNodeType = getModelVerTopWidgetType( transId, fromAppId,"", "", passedModelName );
+                               modInfoStr = "modelName = (" + passedModelName + ")"; 
+                       }
+                       
+                       if( modTopNodeType.equals("") ){
+                               if( (passedTopNodeType == null) || passedTopNodeType.equals("") ){
+                                       String msg = "Could not determine the top-node nodeType for this request. modelInfo: [" + modInfoStr + "]";
+                                       throw new AAIException("AAI_6118", msg);
+                               }
+                               else {
+                                       // We couldn't find a top-model-type based on passed in model info, but they
+                                       // gave us a type to use -- so use it.
+                                       modTopNodeType = passedTopNodeType;
+                               }
+                       }
+                       else {
+                               // we did get a topNode type based on model info - make sure it doesn't contradict 
+                               // the passsed-in one (if there is one)
+                               if( passedTopNodeType != null && !passedTopNodeType.equals("") 
+                                               && !passedTopNodeType.equals(modTopNodeType) ){
+                                       throw new AAIException("AAI_6120", "topNodeType passed in [" + passedTopNodeType 
+                                                       + "] does not match nodeType derived for model info passed in: ["
+                                                       + modTopNodeType + "]"); 
+                               }
+                       }
+                               
+                       List<String> modelVersionIds2Check = new ArrayList<>();
+                       if( (passedModelName != null && !passedModelName.equals("")) ){
+                               // They passed a modelName, so find all the model UUIDs (model-version-id's) that map to this
+                               modelVersionIds2Check = getModelVerIdsUsingName(transId, fromAppId, passedModelName);
+                       }
+                       if( (passedModelVersionId != null && !passedModelVersionId.equals("")) ){
+                               // They passed in a modelNameVersionId
+                               if( modelVersionIds2Check.isEmpty() ){
+                                       // There was no modelName passed, so we can use the passed modelNameVersionId
+                                       modelVersionIds2Check.add(passedModelVersionId);
+                               }
+                               else if( modelVersionIds2Check.contains(passedModelVersionId) ){
+                                       // The passed in uuid does not conflict with what we got using the passed-in modelName.
+                                       // We'll just use the passed in uuid in this case.
+                                       // Hopefully they would not be passing strange combinations like this, but we'll try to deal with it.
+                                       modelVersionIds2Check = new ArrayList<>();  // Clear out what we had
+                                       modelVersionIds2Check.add(passedModelVersionId);
+                               }
+                       }
+                       
+                       // We should now be OK with our topNodeType for this request, so we can look for the actual startNodes
+                       for( int i=0; i < startNodeFilterArrayOfHashes.size(); i++ ){
+                               // Locate the starting node which will be used to look which corresponds to this set of filter data
+                               Vertex startVtx = null;
+                               try {
+                                       Optional<Vertex> result = dbMethHelper.searchVertexByIdentityMap(modTopNodeType, startNodeFilterArrayOfHashes.get(i));
+                                       if (!result.isPresent()) {
+                                               throw new AAIException("AAI_6114", "No Node of type " + modTopNodeType + " found for properties");
+                                       }
+                                       startVtx = result.get();
+                               }
+                               catch( AAIException e ){
+                                       String msg = "Could not find startNode of type = [" + modTopNodeType +  "], given these params: "  
+                                                       + startNodeFilterArrayOfHashes.get(i) + ". msg # from getUniqueNode() = " + e.getMessage();
+                                       throw new AAIException("AAI_6114", msg);
+                               }
+                       
+                               String vid = startVtx.id().toString();
+                               String personaModInvId = startVtx.<String>property("model-invariant-id-local").orElse(null);
+                               String personaModVerId = startVtx.<String>property("model-version-id-local").orElse(null);
+                                       
+                               // Either this start-node has persona info (which should not contradict any passed-in model info)
+                               //    or they should have passed in the model to use - so we'd just use that.
+                               if( personaModVerId != null && !personaModVerId.equals("") ){
+                                       // There is persona data in this start-node.  So make sure it doesn't contradict any "passed" stuff
+                                       if( modelVersionIds2Check.isEmpty()  
+                                                       && (passedModelInvId == null || passedModelInvId.equals("")) ){
+                                               // They didn't pass any model info, so use the persona one.
+                                               startVertInfo.put(vid, personaModVerId);
+                                       }
+                                       else if( modelVersionIds2Check.isEmpty() 
+                                                       && (passedModelInvId != null && !passedModelInvId.equals("")) ){
+                                               // They passed in just the modelId - so check it
+                                               if( passedModelInvId.equals(personaModInvId) ){
+                                                       startVertInfo.put(vid, personaModVerId);
+                                               }
+                                       }
+                                       else if( !modelVersionIds2Check.isEmpty() 
+                                                       && (passedModelInvId == null || passedModelInvId.equals("")) ){
+                                               // They passed in just modelVersionId - so check
+                                               if( modelVersionIds2Check.contains(personaModVerId) ){
+                                                       startVertInfo.put(vid, personaModVerId);
+                                               }
+                                       }       
+                                       else if( !modelVersionIds2Check.isEmpty() 
+                                                       && (passedModelInvId != null && !passedModelInvId.equals("")) ){
+                                               // We have BOTH a modelVersionIds and a modelId to check 
+                                               if( passedModelInvId.equals(personaModInvId) 
+                                                               && modelVersionIds2Check.contains(personaModVerId) ){
+                                                       startVertInfo.put(vid, personaModVerId);
+                                               }
+                                       }
+                               }
+                               else {
+                                       // This start node did not have persona info -- so we will use the passed in model info if they passed one
+                                       if( passedModelVersionId!= null && !passedModelVersionId.equals("") ){
+                                               // The model-version-id uniquely identifies a model-ver, so we can use it.
+                                               startVertInfo.put(vid, passedModelVersionId);
+                                       }
+                                       else {
+                                               throw new AAIException("AAI_6118", "Found startNode but since it does not have persona data, the " +
+                                                               " model-version-id is required. "); 
+                                       }
+                               }
+                       }
+               }
+               
+               return startVertInfo;
+               
+       }//end of  getStartNodesAndModVersionIds()
+               
+
+       /**
+        * Query by model. (really model-ver)
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param modelVersionId the model-version-id (unique id in model-ver)
+        * @param modelInvariantId the model-invariant-id (unique id in model)
+        * @param modelName the model name
+        * @param topNodeType - optional (needed if neither model-invariant-id nor model-version-id is passed)
+        * @param startNodeFilterArrayOfHashes the start node filter array of hashes -- optional (used to locate the first node(s) of instance data)
+        * @param apiVer the api ver
+        * @return resultSet
+        * @throws AAIException the AAI exception
+        */
+       public List<ResultSet> queryByModel( String transId, String fromAppId,
+                       String modelVersionId, 
+                       String modelInvariantId,
+                       String modelName,
+                       String topNodeType,
+                       List<Map<String,Object>> startNodeFilterArrayOfHashes, 
+                       String apiVer ) 
+                                       throws AAIException{
+       
+               final String transId_f = transId;
+               final String fromAppId_f = fromAppId;
+               final String modelVersionId_f = modelVersionId;
+               final String modelInvId_f = modelInvariantId;
+               final String modelName_f = modelName;
+               final String topNodeType_f = topNodeType;
+               final List<Map<String,Object>> startNodeFilterArrayOfHashes_f = startNodeFilterArrayOfHashes; 
+               final String apiVer_f = apiVer; 
+               
+               // Find out what our time-limit should be
+               int timeLimitSec = 0;
+               String timeLimitString = AAIConfig.get("aai.model.query.timeout.sec");
+               if( timeLimitString != null && !timeLimitString.equals("") ){
+                       try {
+                               timeLimitSec = Integer.parseInt(timeLimitString);
+                       }
+                       catch ( Exception nfe ){
+                               // Don't worry, we will leave the limit as zero - which tells us not to use it.
+                       }
+               }
+               
+               if( timeLimitSec <= 0 ){
+                       // We will NOT be using a timer
+                       return queryByModel_Timed( transId, fromAppId,
+                                       modelVersionId, 
+                                       modelInvariantId,
+                                       modelName,
+                                       topNodeType,
+                                       startNodeFilterArrayOfHashes, 
+                                       apiVer );
+               }
+               
+               List<ResultSet> resultList = new ArrayList<>();
+               TimeLimiter limiter = new SimpleTimeLimiter();
+               try {
+                       resultList = limiter.callWithTimeout(new Callable <List<ResultSet>>() {
+                           public List<ResultSet> call() throws AAIException {
+                             return queryByModel_Timed( transId_f, fromAppId_f,
+                                               modelVersionId_f, 
+                                               modelInvId_f,
+                                               modelName_f,
+                                               topNodeType_f,
+                                               startNodeFilterArrayOfHashes_f, 
+                                               apiVer_f );
+                           }
+                         }, timeLimitSec, TimeUnit.SECONDS, true);
+               } 
+               catch (AAIException ae) {
+                       // Re-throw AAIException so we get can tell what happened internally
+                       throw ae;
+               }
+               catch (UncheckedTimeoutException ute) {
+                       throw new AAIException("AAI_6140", "Query Processing Limit exceeded. (limit = " + timeLimitSec + " seconds)");
+               }
+               catch (Exception e) {
+                       throw new AAIException("AAI_6128", "Unexpected exception in queryByModel(): " + e.getMessage() );
+               }
+
+               return resultList;
+       }
+       
+               
+       /**
+        * Query by model (model-ver) timed.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param modelVersionId the model-version-id (unique id in model-ver)
+        * @param modelInvariantId the model-invariant-id (unique id in model)
+        * @param modelName the model name
+        * @param topNodeType the top node type
+        * @param startNodeFilterArrayOfHashes the start node filter array of hashes
+        * @param apiVer the api ver
+        * @return the array list
+        * @throws AAIException the AAI exception
+        */
+       public List<ResultSet> queryByModel_Timed( String transId, String fromAppId,
+                       String modelVersionId,   
+                       String modelInvariantId,
+                       String modelName,
+                       String topNodeType,
+                       List<Map<String,Object>> startNodeFilterArrayOfHashesVal, 
+                       String apiVer ) 
+                                       throws AAIException{
+       
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+                               
+               List<ResultSet> resultArray = new ArrayList<>();
+               
+               // NOTE: this method can be used for different styles of queries:
+               //   a) They could pass neither a modelVersionId or a modelInvariantId but just pass a set of data defining start-nodes.
+               //      Note - with no model info, we need them to pass the startNodeType for us to be able to use the
+               //      start-node-filter data.  We would look at each start node and ensure that each has persona-model info.  
+               //      Then use whatever model corresponds to each instance to pull that instance's data.
+               //   b) They could pass a modelInvariantId, but no modelVersionId and no startNode info.   In this case, we
+               //      Would look in the database for all nodes that have a model-invariant-id-local that matches what was 
+               //      passed, and then for each of those instances, pull the data based on the corresponding model.
+               //   c) They could pass a model-version-id, but no startNode info. We'd make sure that if a 
+               //      model-invariant-id was also passed, that it does not conflict - but it really should be null if they
+               //      are passing a full model-version-id.   Like case -b-, we'd do a query for all nodes
+               //      that have persona info that corresponds to the model-version-id passed and then 
+               //      collect data for each one.
+               //   d) They could pass either modelVersionId or modelInvariantId AND startNodeFilter info.  In this case we
+               //      would look at the model info to figure out what the top-node-type is, then look at the 
+               //      top-node instances based on the startNodeFilter.   We'd only collect data for each instance if
+               //      it's persona model info matches what was passed in.
+               
+               
+               // Sorry to do this, but code that gets called with an empty hash as the first array element was causing errors
+               List<Map<String,Object>> startNodeFilterArrayOfHashes = new ArrayList <Map<String,Object>>();
+               if( !startNodeFilterArrayOfHashesVal.isEmpty() ){
+                       Map<String,Object> tmpH = startNodeFilterArrayOfHashesVal.get(0);
+                       if( !tmpH.isEmpty() ){
+                               for( int i=0; i < startNodeFilterArrayOfHashesVal.size(); i++ ){
+                                       startNodeFilterArrayOfHashes.add( startNodeFilterArrayOfHashesVal.get(i) );
+                               }
+                       }
+               }
+                               
+               // ----------------------------------------------------------------------------------------------------------
+               // Get a Hash of all the start-nodes (top instance-data node for a model-ver where we will 
+               // start collecting data) for startNode2ModelVerHash:  
+               //                      key = vertex-id for the startNode, 
+               //                      value = model-version-id for the corresponding model-ver   
+               // ----------------------------------------------------------------------------------------------------------
+               Map<String, String> startNode2ModelVerHash = getStartNodesAndModVersionIds( transId, fromAppId,
+                               modelVersionId, modelInvariantId, modelName, topNodeType,
+                               startNodeFilterArrayOfHashes, apiVer ); 
+               
+               //System.out.println("\nDEBUG -- Here's a dump of the startnodes/model-vers: " + startNode2ModelVerHash.toString()); 
+               
+               // --------------------------------------------------------------------------------------------------------
+               // Figure out what-all models (model-ver nodes) we will be dealing with 
+               // Note - Instances must all use the same type of start-node, but do not have to all use the same model-ver.
+               // --------------------------------------------------------------------------------------------------------
+               Map<String, Vertex> distinctModelVersHash = new HashMap<>(); 
+                       // For distinctModelVersHash:  key = modelVersionId, val= modelVerVertex
+               String startNodeType = "";
+               if( topNodeType != null && !topNodeType.equals("") ){
+                       startNodeType = topNodeType;
+               }
+
+               List<String> skipModelVerIdList = new ArrayList<>();
+               List<String> skipStartVertVerIdList = new ArrayList<>();
+               Set <String> snKeySet = startNode2ModelVerHash.keySet();
+               Iterator<String> startNodeIterator = snKeySet.iterator();
+               while( startNodeIterator.hasNext() ){
+                       String modVerIdKey = (String) startNodeIterator.next();  
+                       String modVerId = startNode2ModelVerHash.get(modVerIdKey);
+                       if( !distinctModelVersHash.containsKey(modVerId) ){
+                               // First time seeing this model-version-id
+                               Vertex modVerVtx = getNodeUsingUniqueId(transId, fromAppId, "model-ver", 
+                                               "model-version-id", modVerId);
+                               String tmpNodeType = "";
+                               try {
+                                       tmpNodeType = getModelVerTopWidgetType( modVerVtx, "" );
+                               }
+                               catch( AAIException ae ){
+                                       // There must be some old bad data in the db - we will skip over this model-ver since its
+                                       // model is not good anymore - but will log that this is happening.
+                                       skipModelVerIdList.add(modVerId);
+                                       skipStartVertVerIdList.add(modVerIdKey);
+                                       System.out.println(">>>  WARNING - will not collect model data for this vertex since " +
+                                                       "it uses an inconsistant model-ver model.  Model-version-id = " + modVerId );
+                               }
+                               
+                               if( tmpNodeType != null && !tmpNodeType.equals("") ){
+                                       if( startNodeType.equals("") ){
+                                               startNodeType = tmpNodeType;
+                                       }
+                                       else if( !startNodeType.equals(tmpNodeType) ){
+                                               String msg = "Conflict between startNode types for models involved: [" + startNodeType
+                                                               + "], [" + tmpNodeType + "]";
+                                               throw new AAIException("AAI_6125", msg);
+                                       }
+                                       distinctModelVersHash.put(modVerId, modVerVtx);
+                               }
+                       }
+               }
+               
+               //System.out.println("\nDEBUG -- Here's a dump of the DISTINCT model-ver hash: " + distinctModelVersHash.toString() );
+       
+               // ------------------------------------------------------------------------------------------------------
+               // Get the "valid-next-step" hash for each distinct model-ver
+               // While we're at it, get a mapping of model-invariant-id|model-version to model-version-id for 
+               //     the model-vers being used
+               // ------------------------------------------------------------------------------------------------------
+               Map<String, Multimap<String, String>> validNextStepHash = new HashMap<>(); 
+                       // validNextStepHash:   key = modelVerId, value = nextStepMap
+               Set <String> keySet = distinctModelVersHash.keySet();
+               Iterator<String> modelVerIterator = keySet.iterator();
+               while( modelVerIterator.hasNext() ){
+                       String modVerKey = (String) modelVerIterator.next();
+                       if( ! skipModelVerIdList.contains(modVerKey) ){
+                               Vertex modelVerVtx = (Vertex)distinctModelVersHash.get(modVerKey);
+                               Multimap<String, String> tmpTopoMap = genTopoMap4ModelVer( transId, fromAppId,
+                                               modelVerVtx, modVerKey, dbMaps );
+                               validNextStepHash.put(modVerKey, tmpTopoMap);
+                       }
+               } 
+                               
+               // -------------------------------------------------------------------------------------------------
+               // Figure out what the "start-node" for each instance will be (plus the info we will use to 
+               //       represent that in our topology)
+               // -------------------------------------------------------------------------------------------------
+               List<String> failedPersonaCheckVids = new ArrayList<>();
+               Map<String, String> firstStepInfoHash = new HashMap<>(); 
+                       // For firstStepInfoHash:   key = startNodeVtxId, val=topNodeType plus personaData if applicable
+                       //                            ie. the value is what we'd use as the "first-step" for this model.
+               if( !nodeTypeSupportsPersona( startNodeType, dbMaps) ){
+                       // This node type doesn't have persona info, so we just use startNodeType for the first-step-info 
+                       snKeySet = startNode2ModelVerHash.keySet();
+                       startNodeIterator = snKeySet.iterator();
+                       while( startNodeIterator.hasNext() ){
+                               String vtxKey = (String) startNodeIterator.next();
+                               firstStepInfoHash.put(vtxKey,startNodeType);
+                       }
+               }
+               else { 
+                       // Need to check that this node's persona data is good and if it is - use it for the first step info
+                       snKeySet = startNode2ModelVerHash.keySet();
+                       startNodeIterator = snKeySet.iterator();
+                       while( startNodeIterator.hasNext() ){
+                               String vtxKey = (String) startNodeIterator.next();
+                               Iterator<Vertex> vtxIterator = this.engine.asAdmin().getReadOnlyTraversalSource().V(vtxKey);
+                               Vertex tmpVtx = (Vertex)vtxIterator.next();
+                               String thisVtxModelVerId = startNode2ModelVerHash.get(vtxKey);
+                               if( skipModelVerIdList.contains(thisVtxModelVerId) ){
+                                       // Skip this vertex because it uses a model-ver that is bad
+                                       continue;
+                               }
+                               Vertex modelVerVtx = (Vertex)distinctModelVersHash.get(thisVtxModelVerId);
+                               Vertex modelVtx = getModelGivenModelVer( modelVerVtx, "" );
+                               String modInvId = modelVtx.<String>property("model-invariant-id").orElse(null);
+                               String personaModInvId = tmpVtx.<String>property("model-invariant-id-local").orElse(null);
+                               String personaModVerId = tmpVtx.<String>property("model-version-id-local").orElse(null);
+                               if( modInvId.equals(personaModInvId) && thisVtxModelVerId.equals(personaModVerId) ){
+                                       String tmpPersonaInfoStr = startNodeType + "," + personaModInvId + "," + personaModVerId;
+                                       firstStepInfoHash.put(vtxKey, tmpPersonaInfoStr );
+                               }
+                               else { 
+                                       // we won't use this start node below when we collect data because it should have
+                                       // had persona data that matched it's model - but it did not.
+                                       failedPersonaCheckVids.add(vtxKey);
+                               }
+                       }       
+               }       
+
+               //System.out.println("\nDEBUG -- Here's a dump of the firstStepInfoHash hash: " + firstStepInfoHash.toString() );
+               
+               // ------------------------------------------------------------------------------------------------
+               // Loop through each start-node, collect it's data using collectInstanceData() and put the 
+               //      resultSet onto the resultArray.
+               // ------------------------------------------------------------------------------------------------
+               
+               // Make sure they're not bringing back too much data
+               String maxString = AAIConfig.get("aai.model.query.resultset.maxcount");
+               if( maxString != null &&  !maxString.equals("") ){
+                       int maxSets = 0;
+                       try {
+                               maxSets = Integer.parseInt(maxString);
+                       }
+                       catch ( Exception nfe ){
+                               // Don't worry, we will leave the max as zero - which tells us not to use it.
+                       }
+                       
+                       if( maxSets > 0 && (startNode2ModelVerHash.size() > maxSets) ){
+                               String msg = " Query returns " + startNode2ModelVerHash.size() + " resultSets.  Max allowed is: " + maxSets;
+                               throw new AAIException("AAI_6141", msg);
+                       }
+               }
+               
+               snKeySet = startNode2ModelVerHash.keySet();
+               startNodeIterator = snKeySet.iterator();
+               while( startNodeIterator.hasNext() ){
+                       String topNodeVtxId  = (String) startNodeIterator.next();
+                       if( failedPersonaCheckVids.contains(topNodeVtxId) ){
+                               // Skip this vertex because it failed it's persona-data check above
+                               continue;
+                       }
+                       if( skipStartVertVerIdList.contains(topNodeVtxId) ){
+                               // Skip this vertex because it uses a model-ver that is bad
+                               continue;
+                       }
+                       
+                       Iterator<Vertex> vtxIterator = this.engine.asAdmin().getReadOnlyTraversalSource().V(topNodeVtxId);
+                       Vertex tmpStartVtx = (Vertex)vtxIterator.next();
+                       String elementLocationTrail = firstStepInfoHash.get(topNodeVtxId); 
+                       String modelVerId = startNode2ModelVerHash.get(topNodeVtxId);
+                       Multimap<String, String> validNextStepMap = validNextStepHash.get(modelVerId);
+                       
+                       List<String> vidsTraversed = new ArrayList<>();
+                       Map<String,String> emptyDelKeyHash = new HashMap<>();
+                       Map<String,String> emptyNQElementHash = new HashMap<>();  // Only applies to Named Queries
+                       ResultSet tmpResSet = collectInstanceData( transId, fromAppId, 
+                                       tmpStartVtx, elementLocationTrail, 
+                                       validNextStepMap, vidsTraversed, 0, emptyDelKeyHash, emptyNQElementHash, apiVer );
+                       
+                       resultArray.add(tmpResSet);
+               }
+               
+               return resultArray;
+               
+       }// queryByModel_Timed()
+       
+                       
+       
+       /**
+        * Run delete by model-ver.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param modelVersionId the model version id -- unique id for a model-ver node
+        * @param topNodeTypeVal the top node type val -- required if no model-version-id is passed
+        * @param startNodeFilterHash the start node filter hash -- used to locate the first node of instance data
+        * @param apiVer the api ver
+        * @param resVersion the res version -- resourceVersion of the top/first widget in the model instance
+        * @return HashMap (keys = vertexIds that were deleted)
+        * @throws AAIException the AAI exception
+        */
+       public Map<String,String> runDeleteByModel( String transId, String fromAppId,
+                       String modelVersionId, String topNodeTypeVal, Map<String,Object> startNodeFilterHash, String apiVer, String resVersion ) 
+                                       throws AAIException{
+               
+               Map<String,String> retHash = new HashMap<>();
+               
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+               // Locate the Model-ver node to be used 
+               Vertex modelVerVtx = null;
+               if( modelVersionId != null && !modelVersionId.equals("") ){
+                       modelVerVtx = getNodeUsingUniqueId(transId, fromAppId, "model-ver", 
+                                       "model-version-id", modelVersionId);
+               }
+               else {
+                       // if they didn't pass the modelVersionId, then we need to use the startNode to figure it out
+                       // Locate the starting node based on the start node params
+                       if( topNodeTypeVal == null || topNodeTypeVal.equals("") ){
+                               throw new AAIException("AAI_6118", "If no model info is passed, then topNodeType is required. ");
+                       }
+                       
+                       Optional<Vertex> result = dbMethHelper.searchVertexByIdentityMap(topNodeTypeVal, startNodeFilterHash);
+                       if (!result.isPresent()) {
+                               throw new AAIException("AAI_6114", "No Node of type " + topNodeTypeVal + " found for properties");
+                       }
+                       Vertex startVtx = result.get();
+                       
+                       String startVertModVerId = startVtx.<String>property("model-version-id-local").orElse(null);
+                       modelVerVtx = getNodeUsingUniqueId(transId, fromAppId, "model-ver", 
+                                       "model-version-id", startVertModVerId);
+               }
+               
+               if( modelVerVtx == null ){
+                       throw new AAIException("AAI_6114", "Could not determine the model-ver for the given input parameters. ");
+               }
+
+               String topNType = "unknown";
+               String modelType = getModelTypeFromModelVer( modelVerVtx, "" );
+               
+               if( modelType.equals("widget") ){
+                       // If they want to delete using a widget-level model..  That is just a delete of the one 
+                       //      instance of one of our nodes.  
+                       String widgModNodeType = modelVerVtx.<String>property("model-name").orElse(null);
+                       if( (widgModNodeType == null) || widgModNodeType.equals("") ){
+                               String msg = "Could not find model-name for the widget model  [" + modelVersionId + "].";
+                               throw new AAIException("AAI_6132", msg);
+                       }
+                       Optional<Vertex> result = dbMethHelper.locateUniqueVertex(widgModNodeType, startNodeFilterHash);
+                       if (!result.isPresent()) {
+                               throw new AAIException("AAI_6114", "No Node of type " + topNType + " found for properties");
+                       }
+                       Vertex widgetVtx = result.get();
+                       String widgId = widgetVtx.id().toString();
+                       serializer.delete(widgetVtx, resVersion, true);
+                       retHash.put(widgId, widgModNodeType);
+                       return retHash;
+               }
+               
+               // ---------------------------------------------------------------------------------
+               // If we got to here, this must be either a service or resource model.
+               // So, we'll need to get a Hash of which parts of the model to delete.
+               //  NOTE- deleteByModel is deleting data based on one specific version of a model.  
+               // ---------------------------------------------------------------------------------
+               String chkFirstNodePersonaModInvId = "";
+               String chkFirstNodePersonaModVerId = "";
+               String personaData = "";
+               Vertex firstModElementVertex = getTopElementForSvcOrResModelVer( modelVerVtx, "" );  
+               topNType = getModElementWidgetType( firstModElementVertex, "" );
+               if( (topNType == null) || topNType.equals("") ){
+                       String msg = "Could not determine the top-node nodeType for model-version-id: [" + modelVersionId + "]";
+                       throw new AAIException("AAI_6132", msg);
+               }
+               if( nodeTypeSupportsPersona(topNType, dbMaps) ){
+                       Vertex modelVtx = getModelGivenModelVer(modelVerVtx,"");
+                       chkFirstNodePersonaModInvId = modelVtx.<String>property("model-invariant-id").orElse(null);
+                       chkFirstNodePersonaModVerId = modelVerVtx.<String>property("model-version-id").orElse(null);
+                       personaData = "," + chkFirstNodePersonaModInvId + "," + chkFirstNodePersonaModVerId;
+               }
+               
+               // Get the deleteKeyHash for this model
+               String incomingTrail = "";
+               Map<String, String> currentHash = new HashMap<>();
+               Map<String, Vertex> modConHash = new HashMap<>();
+               ArrayList <String>  vidsTraversed = new ArrayList<>();
+               Map<String, String> delKeyHash = collectDeleteKeyHash( transId, fromAppId,
+                                 firstModElementVertex, incomingTrail, currentHash, vidsTraversed, 
+                                 0, dbMaps, modConHash, 
+                                 chkFirstNodePersonaModInvId, chkFirstNodePersonaModVerId ); 
+       
+               
+               System.out.println("\n ----DEBUG -----:  Delete Hash for model: [" + modelVersionId + "] looks like: ");
+               for( Map.Entry<String, String> entry : delKeyHash.entrySet() ){
+                       System.out.println("key = [" + entry.getKey() + "], val = [" + entry.getValue() + "]");
+               }
+               System.out.println("\n -----");
+               // Locate the starting node that we'll use to start looking for instance data
+               Optional<Vertex> result = dbMethHelper.searchVertexByIdentityMap(topNType, startNodeFilterHash);
+               if (!result.isPresent()) {
+                       throw new AAIException("AAI_6114", "No Node of type " + topNType + " found for properties");
+               }
+               Vertex startVtx = result.get();
+               if( !chkFirstNodePersonaModInvId.equals("") ){
+                       // NOTE:  For Service or Resource models, if this is a nodeType that supports persona's, then
+                       //              we need to make sure that the start node matches the persona values.
+                       String startVertPersonaModInvId = startVtx.<String>property("model-invariant-id-local").orElse(null);
+                       String startVertPersonaModVerId = startVtx.<String>property("model-version-id-local").orElse(null);
+                       if( !chkFirstNodePersonaModInvId.equals(startVertPersonaModInvId) 
+                                       || !chkFirstNodePersonaModVerId.equals(startVertPersonaModVerId) ){
+                               String msg = "Persona-Model data mismatch for start node (" + topNType +  "), " +
+                                               startNodeFilterHash ;
+                               throw new AAIException("AAI_6114", msg);
+                       }
+               }
+               String topVid = startVtx.id().toString();
+               
+               // Read the model-ver into a Map for processing
+               Multimap <String, String> validNextStepMap = genTopoMap4ModelVer(transId, fromAppId, 
+                               modelVerVtx, modelVersionId, dbMaps );
+                       
+               // Collect the data
+               String elementLocationTrail = topNType + personaData;
+               vidsTraversed = new ArrayList<>();
+               Map<String,String> emptyHash = new HashMap<>();  
+               
+               // Pass emptyHash for the NQElement hash since that parameter only applies to Named Queries
+               ResultSet retResSet = collectInstanceData( transId, fromAppId, 
+                               startVtx, elementLocationTrail, 
+                               validNextStepMap, vidsTraversed, 0, delKeyHash, emptyHash, apiVer );
+               
+               // Note: the new ResultSet will have each element tagged with the del flag so we'll know if it
+               //              should be deleted or not - so loop through the results in a try-block since some things 
+               //              will get auto-deleted by parents before we get to them --- and try to remove each one.
+               String vidToResCheck = topVid;
+               
+               retHash = deleteAsNeededFromResultSet( transId, fromAppId, retResSet, 
+                               vidToResCheck, apiVer, resVersion, emptyHash );
+               //String msgStr = "processed deletes for these vids: (\n"+ retHash.keySet().toString() + ").";
+               
+               return retHash;
+                 
+       }// End of runDeleteByModel()
+
+                               
+                               
+       /**
+        * Delete as needed from result set.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param resSet the res set
+        * @param vidToResCheck -- this vertex will need to have its resource-version checked
+        * @param apiVer the api ver
+        * @param resVersion the res version
+        * @param hashSoFar the hash so far -- hash of what's been deleted so far
+        * @return String
+        * @throws AAIException the AAI exception
+        */
+       public Map<String,String> deleteAsNeededFromResultSet( String transId, String fromAppId,
+                       ResultSet resSet, String vidToResCheck, String apiVer, String resVersion, Map<String,String> hashSoFar ) 
+                                       throws AAIException
+       {
+               Map<String,String> retHash = new HashMap<>();
+               retHash.putAll( hashSoFar );
+               Boolean deleteIt = false;
+                       
+               if( resSet.getVert() == null ){
+                       return retHash;
+               }
+               
+               TitanVertex thisVtx = resSet.getVert();
+               String thisGuyId = "";
+               String thisNT = "";
+               String thisGuyStr = "";
+               
+               try {
+                       if( thisVtx != null &&  !thisVtx.isRemoved() ){
+                               thisGuyId = thisVtx.id().toString();
+                               thisNT = thisVtx.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                               thisGuyStr = thisGuyId + "[" + thisNT + " found at:" + resSet.getLocationInModelSubGraph() + "]";
+                       }
+               }
+               catch (Exception ex) {
+                       // Sometimes things have already been deleted by the time we get to them - just log it.
+                       LOGGER.warn("Exception when deleting " + thisGuyStr + ".  msg = " + ex.getMessage(), ex);
+               }
+               
+               if( thisGuyId.equals("") ){
+                       // The vertex must have already been removed.   Just return.
+                       return retHash;
+               }
+               else {
+                       if( resSet.getNewDataDelFlag() != null && resSet.getNewDataDelFlag().equals("T") ){
+                               LOGGER.info(">>  will try to delete this one >> " + thisGuyStr);
+                               
+                               try {
+                                       Boolean requireResourceVersion = false;
+                                       if( thisGuyId.equals(vidToResCheck) ){
+                                               // This is the one vertex that we want to check the resourceId before deleting
+                                               requireResourceVersion = true;
+                                       }
+                                       this.serializer.delete(thisVtx, resVersion, requireResourceVersion);
+                               }
+                               catch (AAIException ae) {
+                                       String errorCode = ae.getErrorObject().getErrorCode();
+                                       if (  errorCode.equals("6130") ||  errorCode.equals("6131") ) {
+                                               // They didn't pass the correct resource-version for the top node.
+                                               throw ae;
+                                       }
+                                       else {
+                                               String errText = ae.getErrorObject().getErrorText();
+                                               String errDetail = ae.getMessage();
+                                               LOGGER.warn("Exception when deleting " + thisGuyStr + ".  ErrorCode = " + errorCode + 
+                                                               ", errorText = " + errText + ", details = " + errDetail);
+                                       }
+                               }
+                               catch( Exception e ){
+                                       // We'd expect to get a "node not found" here sometimes depending on the order that 
+                                       // the model has us finding / deleting nodes.
+                                       // Ignore the exception - but log it so we can see what happened.
+                                       LOGGER.warn("Exception when deleting " + thisGuyStr + e.getMessage(), e);
+                               }
+                               
+                               // We can't depend on a thrown exception to tell us if a node was deleted since it may
+                               // have been auto=deleted before this removeAaiNode() call.  
+                               // --- Not sure if we would want to check anything here -- because the graph.commit() is done outside of this call.
+                               
+                               deleteIt = true;
+                       }
+                       else {
+                               // --- DEBUG ---- 
+                               System.out.println(">>>>>>> NOT DELETING THIS ONE >>>> " + thisGuyStr );
+                               List<String> retArr = dbMethHelper.getVertexProperties(thisVtx);
+                               for( String info : retArr ){ System.out.println(info); }
+                               // --- DEBUG ----
+                       }
+               }
+               
+               // Now call this routine for the sub-resultSets
+               List <ResultSet> subResultSetList = resSet.getSubResultSet(); 
+               Iterator <ResultSet> subResSetIter = subResultSetList.iterator();
+               while( subResSetIter.hasNext() ){
+                       ResultSet tmpSubResSet = subResSetIter.next();
+                       retHash = deleteAsNeededFromResultSet( transId, fromAppId, tmpSubResSet, 
+                                       vidToResCheck, apiVer, resVersion, retHash );
+               }
+               
+               if( deleteIt ){
+                       retHash.put(thisGuyId, thisGuyStr);
+               }
+               
+               return retHash;
+                               
+       }// deleteAsNeededFromResultSet()
+               
+       
+
+       /**
+        * Query by named query (old version).
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param namedQueryUuid the named query uuid
+        * @param startNodeFilterArrayOfHashes the start node filter array of hashes --used to locate the first nodes of instance data
+        * @param apiVer the api ver
+        * @return resultSet
+        * @throws AAIException the AAI exception
+        */
+       public List<ResultSet> queryByNamedQuery( String transId, String fromAppId,
+                       String namedQueryUuid,  
+                       ArrayList <Map<String,Object>> startNodeFilterArrayOfHashes, 
+                       String apiVer ) 
+                                       throws AAIException{
+       
+               String dummyCutPoint = null;
+               Map<String,Object> dummySecondaryFilterHash = null;
+               
+               return queryByNamedQuery( transId, fromAppId,
+                               namedQueryUuid,  
+                               startNodeFilterArrayOfHashes, 
+                               apiVer,
+                               dummyCutPoint,
+                               dummySecondaryFilterHash ); 
+       }
+       
+
+       /**
+        * Query by named query.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param namedQueryUuid the named query uuid
+        * @param startNodeFilterArrayOfHashes the start node filter array of hashes --used to locate the first nodes of instance data
+        * @param apiVer the api ver
+        * @param secondaryCutPoint nodeType where we will prune if secondary filter is not met
+        * @param secondaryFilterHash secondary filter params
+        * @return resultSet
+        * @throws AAIException the AAI exception
+        */
+       public List<ResultSet> queryByNamedQuery( String transId, String fromAppId,
+                       String namedQueryUuid,  
+                       List<Map<String,Object>> startNodeFilterArrayOfHashes, 
+                       String apiVer,
+                       String secondaryFilterCutPoint,
+                       Map<String,Object> secondaryFilterHash ) 
+                                       throws AAIException{
+       
+               final String transId_f = transId;
+               final String fromAppId_f = fromAppId;
+               final String namedQueryUuid_f = namedQueryUuid;
+               final List<Map<String,Object>> startNodeFilterArrayOfHashes_f = startNodeFilterArrayOfHashes; 
+               final String apiVer_f = apiVer; 
+               final String secondaryFilterCutPoint_f = secondaryFilterCutPoint; 
+               final Map<String,Object> secondaryFilterHash_f = secondaryFilterHash;   
+               
+               // Find out what our time-limit should be
+               int timeLimitSec = 0;
+               String timeLimitString = AAIConfig.get("aai.model.query.timeout.sec");
+               if( timeLimitString != null && !timeLimitString.equals("") ){
+                       try {
+                               timeLimitSec = Integer.parseInt(timeLimitString);
+                       }
+                       catch ( Exception nfe ){
+                               // Don't worry, we will leave the limit as zero - which tells us not to use it.
+                       }
+               }
+
+               if( timeLimitSec <= 0 ){
+                       // We will NOT be using a timer
+                       return queryByNamedQuery_Timed( transId, fromAppId,
+                                       namedQueryUuid,
+                                       startNodeFilterArrayOfHashes, 
+                                       apiVer,
+                                       secondaryFilterCutPoint_f,
+                                       secondaryFilterHash_f );
+               }
+               
+               List<ResultSet> resultList = new ArrayList<>();
+               TimeLimiter limiter = new SimpleTimeLimiter();
+               try {
+                       resultList = limiter.callWithTimeout(new Callable <List<ResultSet>>() {
+                           public List<ResultSet> call() throws AAIException {
+                             return queryByNamedQuery_Timed( transId_f, fromAppId_f,
+                                                       namedQueryUuid_f,
+                                                       startNodeFilterArrayOfHashes_f, 
+                                                       apiVer_f,
+                                                       secondaryFilterCutPoint_f,
+                                                       secondaryFilterHash_f );
+                           }
+                       }, timeLimitSec, TimeUnit.SECONDS, true);
+                       
+               } 
+               catch (AAIException ae) {
+                       // Re-throw AAIException so we get can tell what happened internally
+                       throw ae;
+               }
+               catch (UncheckedTimeoutException ute) {
+                       throw new AAIException("AAI_6140", "Query Processing Limit exceeded. (limit = " + timeLimitSec + " seconds)");
+               }
+               catch (Exception e) {
+                       throw new AAIException("AAI_6128", "Unexpected exception in queryByNamedQuery(): " + e.getMessage() );
+               }
+
+               return resultList;
+       }
+       
+       
+       /**
+        * Query by named query timed.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param namedQueryUuid the named query uuid
+        * @param startNodeFilterArrayOfHashes the start node filter array of hashes --used to locate the first nodes of instance data  
+        * @param apiVer the api ver
+        * @param secondaryFilterCutPoint the nodeType where we will parse for the secondary Filter
+        * @param secondaryFilterHash the secondary filter hash 
+        * @return resultSet
+        * @throws AAIException the AAI exception
+        */
+       public List<ResultSet> queryByNamedQuery_Timed( String transId, String fromAppId,
+                       String namedQueryUuid,  
+                       List<Map<String,Object>> startNodeFilterArrayOfHashes, 
+                       String apiVer,
+                       String secondaryFilterCutPoint,
+                       Map<String,Object> secondaryFilterHash 
+                       ) 
+                                       throws AAIException{
+               
+               // Locate the Query to be used
+               Vertex queryVtx = getNodeUsingUniqueId(transId, fromAppId, "named-query", 
+                               "named-query-uuid", namedQueryUuid);
+               
+               // Get the first/top named-query-element used by this query
+               Iterator<Vertex> vertI = this.traverseIncidentEdges(EdgeType.TREE, queryVtx, "named-query-element");
+               Vertex firstNqElementVert = null;
+               int count = 0;
+               String topNType = "";
+               while( vertI != null && vertI.hasNext() ){
+                       firstNqElementVert = vertI.next();
+                       count++;
+                       topNType = getNqElementWidgetType( transId, fromAppId,  firstNqElementVert, "" );
+               }
+               
+               if( count < 1 ){
+                       // A named query must start with a single top element
+                       throw new AAIException("AAI_6133", "No top-node defined for named-query-uuid = [" + namedQueryUuid + "]");
+               }
+               else if( count > 1 ){
+                       // A named query should start with a single top element
+                       throw new AAIException("AAI_6133", "More than one top-node defined for named-query-uuid = [" + namedQueryUuid + "]");
+               }
+               if( (topNType == null) || topNType.equals("") ){
+                       String msg = "Could not determine the top-node nodeType for Named Query: [" + namedQueryUuid + "]";
+                       throw new AAIException("AAI_6133", msg);
+               }
+               
+               // Read the topology into a hash for processing
+               Multimap <String, String> validNextStepMap = genTopoMap4NamedQ(transId, fromAppId, queryVtx, namedQueryUuid);
+
+               List<Vertex> startVertList = new ArrayList<>();
+               if( startNodeFilterArrayOfHashes.size() == 1 ){
+                       // If there is only one set of startFilter info given, then allow it to possibly not be
+                       // defining just one start node.
+                       Map<String, Object> cleanHash = new HashMap<>();
+                       Map<String, Object> tmpHash = startNodeFilterArrayOfHashes.get(0);
+                       Set <String> propKeySet = tmpHash.keySet();
+                       Iterator<String> propIter = propKeySet.iterator();
+                       Introspector obj = loader.introspectorFromName(topNType);
+                       Set<String> keys = obj.getKeys();
+                       boolean foundIndexedField = false;
+                       int propertiesSet = 0;
+                       while( propIter.hasNext() ){
+                               String oldVtxKey = (String) propIter.next(); 
+                               String newKey = oldVtxKey;
+                               String [] parts = oldVtxKey.split("\\.");
+                               if( parts.length == 2 ){
+                                       newKey = parts[1];
+                               }
+                               Object obVal = tmpHash.get(oldVtxKey);
+                               if (obj.hasProperty(newKey)) {
+                                       if (keys.contains(newKey)) {
+                                               foundIndexedField = true;
+                                       }
+                                       obj.setValue(newKey, obVal);
+                                       propertiesSet++;
+                               }
+                       }
+                       //we found all the properties in the startNodeType
+                       if (propertiesSet == propKeySet.size()) {
+                               if (foundIndexedField) {
+                                       QueryBuilder builder = this.engine.getQueryBuilder().exactMatchQuery(obj);
+                                       startVertList = builder.toList();
+                               } else {
+                                       //force a filter from aai-node-type
+                                       QueryBuilder builder = this.engine.getQueryBuilder().createContainerQuery(obj).exactMatchQuery(obj);
+                                       startVertList = builder.toList();
+                               }
+                       } else {
+                               Optional<Vertex> tmpVtx = dbMethHelper.searchVertexByIdentityMap(topNType, startNodeFilterArrayOfHashes.get(0));
+                               // Only found one, so just use it.
+                               if (tmpVtx.isPresent()) {
+                                       startVertList.add(tmpVtx.get());
+                               }
+                       }
+               }
+               else {
+                       // Since they give an array of startNodeFilterHash info, we expect each one
+                       // to just point to one node.
+                       for( int i = 0; i < startNodeFilterArrayOfHashes.size(); i++ ){
+                               // Locate the starting node for each set of data
+                               Optional<Vertex> tmpVtx = dbMethHelper.searchVertexByIdentityMap(topNType, startNodeFilterArrayOfHashes.get(i));
+                               if (tmpVtx.isPresent()) {
+                                       startVertList.add(tmpVtx.get());
+                               }
+                       }
+               }
+               
+               if (startVertList.isEmpty()) {
+                       throw new AAIException("AAI_6114", "No Node of type " + topNType + " found for properties");
+               }
+               // Make sure they're not bringing back too much data
+               String maxString = AAIConfig.get("aai.model.query.resultset.maxcount");
+               if( maxString != null &&  !maxString.equals("") ){
+                       int maxSets = Integer.parseInt(maxString);
+                       if( startVertList.size() > maxSets ){
+                               String msg = " Query returns " + startVertList.size() + " resultSets.  Max allowed is: " + maxSets;
+                               throw new AAIException("AAI_6141", msg);
+                       }
+               }
+               
+               // Loop through each start node and get its data
+               List<ResultSet> resSetList = new ArrayList<>();
+               for( int i = 0; i < startVertList.size(); i++ ){
+                       Vertex startVtx = startVertList.get(i);
+                       // Collect the data
+                       String elementLocationTrail = topNType;
+                       ArrayList <String>  vidsTraversed = new ArrayList<>();
+                       Map<String,String> emptyDelKeyHash = new HashMap<>();  // Does not apply to Named Queries
+                                       
+                       // Get the mapping of namedQuery elements to our widget topology for this namedQuery
+                       String incomingTrail = "";
+                       Map<String, String> currentHash = new HashMap<>();
+                       
+                       Map<String,String> namedQueryElementHash = collectNQElementHash( transId, fromAppId,
+                                         firstNqElementVert, incomingTrail, currentHash, vidsTraversed, 0 );
+                       
+                       vidsTraversed = new ArrayList<>();
+                       ResultSet tmpResSet = collectInstanceData( transId, fromAppId, 
+                                       startVtx, elementLocationTrail, 
+                                       validNextStepMap, vidsTraversed, 0, emptyDelKeyHash, namedQueryElementHash, apiVer );
+                       resSetList.add(tmpResSet);
+               }
+               
+               // If a secondary filter was defined, we will prune the collected instance data result set(s) based on it.
+               List<ResultSet> prunedResSetList = new ArrayList<>();
+               if( resSetList != null && !resSetList.isEmpty() ){
+                       for( int i = 0; i < resSetList.size(); i++ ){
+                               if( secondaryFilterCutPoint == null || secondaryFilterCutPoint.equals("") || secondaryFilterHash == null ){
+                                       // They didn't want to do any pruning, so just use the results we already had
+                                       prunedResSetList.add(resSetList.get(i));
+                               }
+                               else {
+                                       ResultSet tmpResSet = pruneResultSet(resSetList.get(i), secondaryFilterCutPoint, secondaryFilterHash);
+                                       if( tmpResSet != null ){
+                                               prunedResSetList.add(tmpResSet);
+                                       }
+                               }
+                       }
+               }
+               
+               // Since a NamedQuery can mark some nodes as "do-not-display", we need to collapse our resultSet so 
+               // does not display those nodes.
+               List<ResultSet> collapsedResSetList = new ArrayList<>();
+               if( prunedResSetList != null && !prunedResSetList.isEmpty() ){
+                       for( int i = 0; i < prunedResSetList.size(); i++ ){
+                               // Note - a single resultSet could be collapsed into many smaller ones if they
+                               //    marked all the "top" node-elements as do-not-output.   Ie. the query may
+                               //    have had a top-node of "generic-vnf" which joins down to different l-interfaces.
+                               //    If they only want to see the l-interfaces, then a single result set
+                               //    would be "collapsed" into many separate resultSets - each of which is 
+                               //    just a single l-interface.
+                               List<ResultSet> tmpResSetList = collapseForDoNotOutput(prunedResSetList.get(i));
+                               if( tmpResSetList != null && !tmpResSetList.isEmpty() ){
+                                       for( int x = 0; x < tmpResSetList.size(); x++ ){
+                                               //showResultSet( tmpResSetList.get(x), 0 ); //DEBUG-- this was just for testing
+                                               collapsedResSetList.add(tmpResSetList.get(x));
+                                       }
+                               }
+                       }
+               }
+               
+               return collapsedResSetList;
+               
+       }// End of queryByNamedQuery()
+
+       
+       /**
+        * Prune a result set as per a secondary filter.
+        *
+        * @param resSetVal the res set val
+        * @param cutPoint the nodeType where the trim will happen
+        * @param secFilterHash hash of properties and values to use as the secondary filter
+        * @return pruned result set
+        * @throws AAIException the AAI exception
+        */
+       public ResultSet pruneResultSet( ResultSet resSetVal, String cutPointType, Map<String,Object> secFilterHash )
+               throws AAIException {
+               
+               // Given a ResultSet and some secondary filter info, do pruning as needed 
+               ResultSet pResSet = new ResultSet();
+                               
+               // For this ResultSet, we will see if we are on a node of the type that is our cutPoint; 
+               //   then only keep it if we peek "below" and see a match for our filter.
+                               
+               String nt = resSetVal.getVert().<String>property(AAIProperties.NODE_TYPE).orElse(null);
+               if( nt != null && nt.equals(cutPointType) ){
+                       // We are on the type of node that may need to be "pruned" along with it's sub-results
+                       if( ! satisfiesFilters(resSetVal, secFilterHash) ){
+                               // Return an empty result set since we are pruning at this level.
+                               return pResSet;
+                       }
+               }
+               
+               // If we made it to here, we will not be pruning at this level, so we will 
+               // be returning a copy of this resultSet that has it's subResults pruned (as needed).
+               pResSet.setVert(resSetVal.getVert());
+               pResSet.setDoNotOutputFlag(resSetVal.getDoNotOutputFlag());
+               pResSet.setExtraPropertyHash(resSetVal.getExtraPropertyHash());
+               pResSet.setLocationInModelSubGraph(resSetVal.getLocationInModelSubGraph());
+               pResSet.setNewDataDelFlag(resSetVal.getNewDataDelFlag());
+               pResSet.setPropertyLimitDesc(resSetVal.getPropertyLimitDesc());
+               pResSet.setPropertyOverRideHash(resSetVal.getPropertyOverRideHash());
+                               
+               if( !resSetVal.getSubResultSet().isEmpty() ){
+                       ListIterator<ResultSet> listItr = resSetVal.getSubResultSet().listIterator();
+                       List<ResultSet> newSubSetList = new ArrayList<>();
+                       while( listItr.hasNext() ){
+                               ResultSet tmpSubResSet = pruneResultSet( listItr.next(), cutPointType, secFilterHash );
+                               if( tmpSubResSet.getVert() != null ){
+                                       // This one wasn't pruned - so keep it.
+                                       newSubSetList.add(tmpSubResSet);
+                               }
+                       }
+                       pResSet.setSubResultSet(newSubSetList);
+               }   
+               
+               return pResSet;
+               
+       }// End pruneResultSet()
+       
+       
+       /**
+        * Satisfies hash of filters.
+        *
+        * @param resSet the res set
+        * @param filterHash the filter hash
+        * @return true, if successful
+        * @throws AAIException the AAI exception
+        */
+       public boolean satisfiesFilters( ResultSet resSet, Map<String,Object> filterHash )  
+                       throws AAIException {
+                 
+                 if( filterHash.isEmpty() ){
+                         // Nothing to look for, so no, we didn't find it.
+                         return false;
+                 }
+                 
+                 Iterator <?> it = filterHash.entrySet().iterator();
+                 while( it.hasNext() ){
+                         Map.Entry<?,?> filtEntry = (Map.Entry<?,?>) it.next();
+                         String propNodeTypeDotName = (filtEntry.getKey()).toString();
+                         String fpv = (filtEntry.getValue()).toString();
+                         
+                         int periodLoc = propNodeTypeDotName.indexOf(".");
+                         if( periodLoc <= 0 ){
+                                 String emsg = "Bad filter param key passed in: [" + propNodeTypeDotName + "].  Expected format = [nodeName.paramName]\n";
+                                 throw new AAIException("AAI_6120", emsg); 
+                         }
+                         else {
+                                 String fnt = propNodeTypeDotName.substring(0,periodLoc);
+                                 String fpn = propNodeTypeDotName.substring(periodLoc + 1);
+                                 if( filterMetByThisSet( resSet, fnt, fpn, fpv ) ){
+                                         //System.out.println(" DEBUG -- satisfied/matched filter: [" + fnt + "|" + fpn + "|" + fpv + "].");
+                                 }
+                                 else {
+                                         //System.out.println(" DEBUG -- NOT satisfied/matched filter: [" + fnt + "|" + fpn + "|" + fpv + "].");
+                                         return false;
+                                 }
+                         }
+                 }
+                 
+                 // Made it through all the filters -- it found what we were looking for.
+                 return true;
+                 
+         }// end of satisfiesFilters()
+       
+       
+       /**
+        * Filter met by this set.
+        *
+        * @param resSet the res set
+        * @param filtNodeType the filt node type
+        * @param filtPropName the filt prop name
+        * @param filtPropVal the filt prop val
+        * @return true, if successful
+        */
+       public boolean filterMetByThisSet( ResultSet resSet, String filtNodeType, String filtPropName, String filtPropVal ) {
+        // Note - we are just looking for a positive match for one filter for this resultSet
+               // NOTE: we're expecting the filter to have a format like this: "nodeType.parameterName:parameterValue"
+               
+                 Vertex vert = resSet.getVert();
+                 if( vert == null ){
+                         return false;
+                 }
+                 else {
+                         String nt = resSet.getVert().<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                         if( nt.equals( filtNodeType ) ){
+                                 if( filtPropName.equals("vertex-id") ){
+                                         // vertex-id can't be gotten the same way as other properties
+                                         String thisVtxId = vert.id().toString();
+                                         if( thisVtxId.equals(filtPropVal) ){
+                                                 return true;
+                                         }
+                                 }
+                                 else {
+                                         Object thisValObj = vert.property(filtPropName).orElse(null);
+                                         if( thisValObj != null ){
+                                                 String thisVal = thisValObj.toString();
+                                                 if( thisVal.equals(filtPropVal) ){
+                                                         return true;
+                                                 }
+                                         }
+                                 }
+                         }
+                 }
+                       
+                 // Didn't find a match at the this level, so check the sets below it meet the criteria
+                 if( resSet.getSubResultSet() != null ){
+                         ListIterator<ResultSet> listItr = resSet.getSubResultSet().listIterator();
+                         while( listItr.hasNext() ){
+                                 if( filterMetByThisSet(listItr.next(), filtNodeType, filtPropName, filtPropVal) ){
+                                         return true;
+                                 }
+                         }
+                 }
+                 
+                 return false;
+                 
+         }// end of filterMetByThisSet()
+         
+
+       
+       /**
+        * Collapse for do not output.
+        *
+        * @param resSetVal the res set val
+        * @return the array list
+        * @throws AAIException the AAI exception
+        */
+       public List<ResultSet> collapseForDoNotOutput( ResultSet resSetVal )
+               throws AAIException {
+               
+               // Given a ResultSet -- if it is tagged to NOT be output, then replace it with 
+               // it's sub-ResultSets if it has any. 
+               List<ResultSet> colResultSet = new ArrayList<>();
+               
+               if( resSetVal.getDoNotOutputFlag().equals("true") ){
+                       // This ResultSet isn't to be displayed, so replace it with it's sub-ResultSets
+                       List<ResultSet> subResList = (ArrayList<ResultSet>) resSetVal.getSubResultSet();
+                       for( int k = 0; k < subResList.size(); k++ ){
+                               List<ResultSet> newSubResList =  collapseForDoNotOutput(subResList.get(k));
+                               colResultSet.addAll(newSubResList);
+                       }
+               }
+               else {
+                       // This set will be displayed
+                       colResultSet.add(resSetVal);
+               }
+               
+               // For each result set now at this level, call this same routine to collapse their sub-resultSets
+               for( int i = 0; i < colResultSet.size(); i++ ){
+                       List<ResultSet> newSubSet = new ArrayList<>();
+                       List<ResultSet> subResList = (ArrayList<ResultSet>) colResultSet.get(i).getSubResultSet();
+                       for( int n = 0; n < subResList.size(); n++ ){
+                               List<ResultSet> newSubResList =  collapseForDoNotOutput(subResList.get(n));
+                               newSubSet.addAll(newSubResList);
+                       }
+                       // Replace the old subResultSet with the collapsed set
+                       colResultSet.get(i).setSubResultSet(newSubSet);
+               }
+               
+               return colResultSet;
+               
+       }// End collapseForDoNotOutput()
+       
+       
+    
+       /**
+        * Collect instance data.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param thisLevelElemVtx the element vtx at this level 
+        * @param thisVertsTrail the this verts trail
+        * @param elementLocationTrail -- trail of nodeTypes that got us here (this element vertex) from the top
+        * @param validNextStepMap the valid next step map -- hash of valid next steps (node types) for this model
+        * @param vidsTraversed the vids traversed -- ArrayList of vertexId's that we traversed to get to this point
+        * @param levelCounter the level counter
+        * @param delKeyHash -- hashMap of which spots on our topology should be deleted during a modelDelete
+        * @param namedQueryElementHash - hashMap which maps each spot in our widget topology to the NamedQueryElemment that it maps to
+        * @param apiVer the api ver
+        * @return resultSet
+        * @throws AAIException the AAI exception
+        */
+       public ResultSet collectInstanceData( String transId, String fromAppId,
+                 Vertex thisLevelElemVtx, 
+                 String thisVertsTrail, 
+                 Multimap <String,String> validNextStepMap,
+                 List<String> vidsTraversed, 
+                 int levelCounter, 
+                 Map<String,String> delKeyHash,  // only applies when collecting data using the default model for delete
+                 Map<String,String> namedQueryElementHash,  // only applies to named-query data collecting
+                 String apiVer
+                 )   throws AAIException {
+               
+         levelCounter++;
+         
+         String thisElemVid = thisLevelElemVtx.id().toString();
+          
+         if( levelCounter > MAX_LEVELS ) {
+                 throw new AAIException("AAI_6125", "collectInstanceData() has looped across more levels than allowed: " + MAX_LEVELS + ". "); 
+         }
+         
+         ResultSet rs = new ResultSet();
+         if( namedQueryElementHash.containsKey(thisVertsTrail) ){
+                 // We're collecting data for a named-query, so need to see if we need to do anything special
+                 String nqElUuid = namedQueryElementHash.get(thisVertsTrail);
+                 Vertex nqElementVtx = getNodeUsingUniqueId(transId, fromAppId, "named-query-element", 
+                                       "named-query-element-uuid", nqElUuid);
+                
+                 String tmpDoNotShow = nqElementVtx.<String>property("do-not-output").orElse(null);
+                 if( tmpDoNotShow != null && tmpDoNotShow.equals("true") ){
+                         rs.setDoNotOutputFlag("true");
+                 }
+                                 
+                 if( namedQueryConstraintSaysStop(transId, fromAppId, nqElementVtx, thisLevelElemVtx, apiVer) ){
+                         // There was a property constraint which says they do not want to collect this vertex or whatever 
+                         // might be below it.  Just return the empty rs here.
+                         return rs;
+                 }
+                 
+                 String propLimDesc = nqElementVtx.<String>property("property-limit-desc").orElse(null);
+                 if( (propLimDesc != null) && !propLimDesc.equals("") ){
+                         if (propLimDesc.equalsIgnoreCase("show-all")) {
+                                 rs.setPropertyLimitDesc(PropertyLimitDesc.SHOW_ALL);
+                         } else if (propLimDesc.equalsIgnoreCase("show-none")) {
+                                 rs.setPropertyLimitDesc(PropertyLimitDesc.SHOW_NONE);
+                         }else if (propLimDesc.equalsIgnoreCase("name-and-keys-only")) {
+                                 rs.setPropertyLimitDesc(PropertyLimitDesc.SHOW_NAME_AND_KEYS_ONLY);
+                         }
+                 }
+
+                 // Look to see if we need to use an Override of the normal properties
+                 Map<String,Object> tmpPropertyOverRideHash = getNamedQueryPropOverRide(transId, fromAppId, nqElementVtx, thisLevelElemVtx, apiVer);
+                 //System.out.println(" DEBUG --- USING this propertyOverride data set on ResSet [" + tmpPropertyOverRideHash.toString() + "]");
+                 rs.setPropertyOverRideHash(tmpPropertyOverRideHash);
+                 
+                 // See if we need to look up any "unconnected" data that needs to be associated with this result set
+                 Map<String,Object> tmpExtraPropHash = getNamedQueryExtraDataLookup(transId, fromAppId, nqElementVtx, thisLevelElemVtx, apiVer);
+                 //System.out.println(" DEBUG --- ADDING this EXTRA Lookup data to the ResSet [" + tmpExtraPropHash.toString() + "]");
+                 rs.setExtraPropertyHash(tmpExtraPropHash);
+         }
+         
+         rs.setVert((TitanVertex)thisLevelElemVtx);
+         rs.setLocationInModelSubGraph(thisVertsTrail);
+         if( delKeyHash.containsKey(thisVertsTrail) && delKeyHash.get(thisVertsTrail).equals("T") ){
+                 rs.setNewDataDelFlag("T");
+         }
+         else {
+                 rs.setNewDataDelFlag("F");
+         }
+               
+         // Use Gremlin-pipeline to just look for edges that go to a valid "next-steps"
+         Collection <String> validNextStepColl = validNextStepMap.get(thisVertsTrail);
+         
+         // Because of how we process linkage-points, we may have duplicate node-types in our next-stepMap (for one step)
+         // So, to keep from looking (and bringing back) the same data twice, we need to make sure our next-steps are unique
+         Set<String> validNextStepHashSet = new HashSet<>();
+         Iterator <String> ntcItr = validNextStepColl.iterator();
+         while( ntcItr.hasNext() ){
+                 String targetStepStr = ntcItr.next();
+                 validNextStepHashSet.add(targetStepStr);
+         }
+         
+         List<String> tmpVidsTraversedList = new ArrayList<>();
+         tmpVidsTraversedList.addAll(vidsTraversed);
+         tmpVidsTraversedList.add(thisElemVid);
+         
+         Iterator <String> ntItr = validNextStepHashSet.iterator();
+         while( ntItr.hasNext() ){
+                 String targetStep = ntItr.next();
+                 // NOTE: NextSteps can either be just a nodeType, or can be a nodeType plus
+                 //     model-invariant-id-local and model-version-id-local (the two persona properties) 
+                 //     if those need to be checked also.
+                 //     When the persona stuff is part of the step, it is a comma separated string.
+                 //     Ie.  "nodeType,model-inv-id-local,model-version-id-local" (the two "persona" props)
+                 //     
+                 String targetNodeType = "";
+                 String pmid = "";
+                 String pmv = "";
+                 Boolean stepIsJustNT = true;
+                 if( targetStep.contains(",") ){
+                         stepIsJustNT = false;
+                         String[] pieces = targetStep.split(",");
+                         if( pieces.length != 3 ){
+                                               throw new AAIException("AAI_6128", "Unexpected format for nextStep in model processing = [" 
+                                                         + targetStep + "]. ");
+                         }
+                         else {
+                                 targetNodeType = pieces[0];
+                                 pmid = pieces[1];
+                                 pmv = pieces[2];
+                         }
+                 }
+                 else {
+                         // It's just the nodeType with no other info
+                         targetNodeType = targetStep;
+                 }
+                 
+                 GraphTraversal<Vertex, Vertex> modPipe = null;
+                 if( stepIsJustNT ){
+                         modPipe = this.engine.asAdmin().getReadOnlyTraversalSource().V(thisLevelElemVtx).both().has(AAIProperties.NODE_TYPE, targetNodeType);
+                 }
+                 else {
+                         modPipe = this.engine.asAdmin().getReadOnlyTraversalSource().V(thisLevelElemVtx).both().has(AAIProperties.NODE_TYPE, targetNodeType).has("model-invariant-id-local",pmid).has("model-version-id-local",pmv);
+                 }
+                 
+                 if( modPipe == null || !modPipe.hasNext() ){
+                        //System.out.println("DEBUG - didn't find any [" + targetStep + "] connected to this guy (which is ok)");
+                 }
+                 else {
+                         while( modPipe.hasNext() ){
+                                 Vertex tmpVert = (Vertex) modPipe.next();
+                                 String tmpVid = tmpVert.id().toString();
+                                 String tmpTrail = thisVertsTrail + "|" + targetStep;
+                                 if( !vidsTraversed.contains(tmpVid) ){
+                                         // This is one we would like to use - so we'll include the result set we get for it 
+                                         ResultSet tmpResSet  = collectInstanceData( transId, fromAppId, 
+                                                               tmpVert, tmpTrail, 
+                                                               validNextStepMap, tmpVidsTraversedList, 
+                                                               levelCounter, delKeyHash, namedQueryElementHash, apiVer );
+                                         
+                                         rs.getSubResultSet().add(tmpResSet);
+                                 }
+                         }
+                 }
+         }
+       
+         return rs;
+         
+       } // End of collectInstanceData()
+
+
+       /**
+        * Gen topo map 4 model.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param modelVerVertex the model-ver vertex
+        * @param modelVerId the model-version-id
+        * @param dbMaps the db maps
+        * @return MultiMap of valid next steps for each potential model-element
+        * @throws AAIException the AAI exception
+        */
+       public Multimap<String, String> genTopoMap4ModelVer( String transId, String fromAppId, 
+                Vertex modelVerVertex, String modelVerId, DbMaps dbMaps )   
+                                 throws AAIException {
+         
+               if( modelVerVertex == null ){
+                       throw new AAIException("AAI_6114", "null modelVerVertex passed to genTopoMap4ModelVer()");
+               }
+               
+               Multimap <String, String> initialEmptyMap = ArrayListMultimap.create();
+               List<String> vidsTraversed = new ArrayList<>();
+               String modelType = getModelTypeFromModelVer( modelVerVertex, "" );
+               if( modelType.equals("widget") ){
+                       // A widget model by itself does not have a topoplogy.  That is - it has no "model-elements" which
+                       // define how it is connected to other things.   All it has is a name which ties it to 
+                       // an aai-node-type
+                       Iterator<Vertex> vertI= this.traverseIncidentEdges(EdgeType.TREE, modelVerVertex, "model-element");
+                       if( vertI != null && vertI.hasNext() ){
+                               throw new AAIException("AAI_6132", "Bad Model Definition: Widget Model has a startsWith edge to a model-element.  " 
+                                               + " model-version-id = " + modelVerId);
+                       }
+                       else {
+                               return initialEmptyMap;
+                       }
+               }
+               
+               String firstModelVerId = modelVerVertex.<String>property("model-version-id").orElse(null);
+               String firstModelVersion = modelVerVertex.<String>property("model-version").orElse(null);
+               if( firstModelVerId == null || firstModelVerId.equals("") || firstModelVersion == null || firstModelVersion.equals("") ){
+                       throw new AAIException("AAI_6132", "Bad Model Definition: Bad model-version-id or model-version.  model-version-id = " 
+                                 + modelVerId);
+               }
+               
+               Vertex firstElementVertex = getTopElementForSvcOrResModelVer( modelVerVertex, "" );
+               Vertex firstEleModVerVtx = getModelVerThatElementRepresents( firstElementVertex, "" );
+               String firstElemModelType = getModelTypeFromModelVer( firstEleModVerVtx, "" );    
+               if( ! firstElemModelType.equals("widget") ){
+                       throw new AAIException("AAI_6132", "Bad Model Definition: First element must correspond to a widget type model.  Model UUID = " 
+                                 + modelVerId);
+               }
+               
+               Vertex firstModVtx = getModelGivenModelVer( modelVerVertex, "" );
+           String firstModelInvId = firstModVtx.<String>property("model-invariant-id").orElse(null);
+           if( firstModelInvId == null || firstModelInvId.equals("") ){
+                       throw new AAIException("AAI_6132", "Bad Model Definition: Could not find model.model-invariant-id given model-ver.model-version-id = " 
+                                 + modelVerId);
+               }
+           
+                Multimap <String, String> collectedMap = collectTopology4ModelVer( transId, fromAppId, 
+                               firstElementVertex, "", initialEmptyMap, vidsTraversed, 0, dbMaps, null, firstModelInvId, firstModelVersion );
+                
+                return collectedMap;
+         
+       } // End of genTopoMap4ModelVer()
+
+
+       public List<String> makeSureItsAnArrayList( String listStringVal ){
+               // We're sometimes getting a String back on db properties that should be ArrayList<String>
+               // Seems to be how they're defined in OXM - whether they use a "xml-wrapper" or not
+               // Need to translate them into ArrayLists sometimes...
+               
+               List<String> retArrList = new ArrayList<String>();
+               String listString = listStringVal;
+               listString = listString.replace(" ",  "");
+               listString = listString.replace("\"",  "");
+               listString = listString.replace("[",  "");
+               listString = listString.replace("]",  "");
+               String [] pieces = listString.split(",");
+               if( pieces != null && pieces.length > 0 ){
+                       for( int i = 0; i < pieces.length; i++ ){
+                               retArrList.add(pieces[i]);
+                       }
+               }
+                       
+               return retArrList;
+       }
+
+
+       /**
+        * Gets the mod constraint hash.
+        *
+        * @param modelElementVtx the model element vtx
+        * @param currentHash -- the current ModelConstraint's that this routine will add to if it finds any.
+        * @return HashMap of model-constraints that will be looked at for this model-element and what's "below" it.
+        * @throws AAIException the AAI exception
+        */
+       public Map<String, Vertex> getModConstraintHash( Vertex modelElementVtx, Map<String, Vertex> currentHash )   
+                                 throws AAIException {
+       
+               // For a given model-element vertex, look to see if there are any "model-constraint" elements that is has 
+               //   an OUT "uses" edge to.   If it does, then get any "constrained-element-set" nodes that are pointed to
+               //   by the "model-constraint".   That will be the replacement "constrained-element-set".  The UUID of the
+               //   "constrained-element-set" that it is supposed to replace is found in the property:
+               //   model-constraint.constrained-element-set-uuid-to-replace   
+               //
+               //   For now, that is the only type of model-constraint allowed, so that is all we will look for.  
+               //   Pass back any of these "constrained-element-set" nodes along with any that were passed in by 
+               //   the "currentHash" parameter.
+                               
+               if( modelElementVtx == null ){
+                       String msg = " null modelElementVtx passed to getModConstraintHash() ";
+                       throw new AAIException("AAI_6114", msg);
+               }
+         
+               String modelType = modelElementVtx.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+               if( modelType == null || (!modelType.equals("model-element")) ){
+                       String msg = " getModConstraintHash() called with wrong type model: [" + modelType + "]. ";
+                       throw new AAIException("AAI_6114", msg);
+               }
+         
+               Map<String, Vertex> thisHash = new HashMap<>();
+               if( currentHash != null ){
+                       thisHash.putAll(currentHash);
+               }
+        
+               int count = 0;
+               List<Vertex> modelConstraintArray = new ArrayList<>();
+               Iterator<Vertex> vertI = this.traverseIncidentEdges(EdgeType.TREE, modelElementVtx, "model-constraint");
+               while( vertI != null && vertI.hasNext() ){
+                       Vertex tmpVert = vertI.next();
+                       String connectToType = tmpVert.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                       if( (connectToType != null) && connectToType.equals("model-constraint") ){
+                               // We need to find the constrained element set pointed to by this and add it to the Hash to return
+                               modelConstraintArray.add(tmpVert);
+                               count++;
+                       }
+               }
+         
+               if( count > 0 ) {
+                       for( int i = 0; i < count; i++ ){
+                               Vertex vtxOfModelConstraint = modelConstraintArray.get(i);
+                               String uuidOfTheOneToBeReplaced = vtxOfModelConstraint.<String>property("constrained-element-set-uuid-2-replace").orElse(null);
+                               // We have the UUID of the constrained-element-set that will be superseded, now find the
+                               // constrained-element-set to use in its place
+                               Iterator<Vertex> mvertI = this.traverseIncidentEdges(EdgeType.TREE, vtxOfModelConstraint, "constrained-element-set");
+                               while( mvertI != null && mvertI.hasNext() ){
+                                       // There better only be one...  
+                                       Vertex tmpVert = mvertI.next();
+                                       String connectToType = tmpVert.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                                       if( (connectToType != null) && connectToType.equals("constrained-element-set") ){
+                                               // This is the "constrained-element-set" that we want to use as the Replacement
+                                               thisHash.put(uuidOfTheOneToBeReplaced, tmpVert );
+                                       }
+                               }
+                       }
+                       return thisHash;
+               }
+               else {
+                       // Didn't find anything to add, so just return what they passed in.
+                       return currentHash;
+               }
+       
+       } // End of getModConstraintHash()
+       
+       /**
+        * Gets the top element vertex for service or resource model.
+        *
+        * @param modelVerVtx the model-ver vertex
+        * @return first element pointed to by this model-ver
+        * @throws AAIException the AAI exception
+        */
+       public Vertex getTopElementForSvcOrResModelVer( Vertex modelVerVtx, String trail )   
+                                 throws AAIException {
+       
+                 // For a "resource" or "service" type model, return the "top" element in that model
+                 if( modelVerVtx == null ){
+                         String msg = " null modelVertex passed to getTopoElementForSvcOrResModelVer() at [" + trail + "]. ";
+                         throw new AAIException("AAI_6114", msg);
+                 }
+                
+                 String modelVerId = modelVerVtx.<String>property("model-version-id").orElse(null);
+                 if( modelVerId == null ){
+                         String nt = modelVerVtx.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                         if( nt != null && !nt.equals("model-ver") ){
+                                 String msg = "Illegal model defined: model element pointing to nodeType: [" 
+                                                 + nt + "], should be pointing to: [model-ver] at [" + trail + "]. ";
+                                 throw new AAIException("AAI_6132", msg);
+                         }
+                 }
+                 
+                 Vertex firstElementVertex = null;
+       
+                 Iterator<Vertex> vertI = this.traverseIncidentEdges(EdgeType.TREE, modelVerVtx, "model-element");
+                 int elCount = 0;
+                 while( vertI != null && vertI.hasNext() ){
+                         elCount++;
+                         firstElementVertex = vertI.next();
+                 }
+                       
+                 if( elCount > 1 ){
+                         String msg = "Illegal model defined: More than one first element defined for model-ver-id = " + 
+                                         modelVerId + " at [" + trail + "]. ";
+                         throw new AAIException("AAI_6132", msg);
+                 }
+                         
+                 if( firstElementVertex == null ){
+                         String msg = "Could not find first model element for model-ver-id = " 
+                                         + modelVerId + " at [" + trail + "]. ";
+                         throw new AAIException("AAI_6132", msg);
+                 }
+                 
+                 return firstElementVertex;
+         
+       } // End of getTopElementForSvcOrResModelVer()
+
+       
+                
+       /**
+        * Gets the named query prop over ride.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param namedQueryElementVertex the named query element vertex
+        * @param instanceVertex the instance vertex
+        * @param apiVer the api ver
+        * @return HashMap of alternate properties to return for this element
+        * @throws AAIException the AAI exception
+        */
+       public Map<String,Object> getNamedQueryPropOverRide( String transId, String fromAppId,
+                       Vertex namedQueryElementVertex, Vertex instanceVertex, String apiVer )   
+                                 throws AAIException {
+               
+               // If this model-element says that they want an alternative set of properties returned, then pull that
+               // data out of the instance vertex.
+               
+               Map<String,Object> altPropHash = new HashMap<>();
+                       
+               if( namedQueryElementVertex == null ){
+                       String msg = " null namedQueryElementVertex passed to getNamedQueryPropOverRide() ";
+                       throw new AAIException("AAI_6114", msg);
+               }
+               
+               List<String> propCollectList = new ArrayList<>();
+               Iterator <VertexProperty<Object>> vpI = namedQueryElementVertex.properties("property-collect-list");
+               while( vpI.hasNext() ){
+                       propCollectList.add((String)vpI.next().value());
+               }
+               
+               for( int i = 0; i < propCollectList.size(); i++ ){
+                       String thisPropName = propCollectList.get(i);
+                       Object instanceVal = instanceVertex.<Object>property(thisPropName).orElse(null);
+                       altPropHash.put(thisPropName, instanceVal);
+               }
+                       
+               return altPropHash;
+         
+       } // End of getNamedQueryPropOverRide()
+
+       
+       /**
+        * Named query constraint says stop.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param namedQueryElementVertex the named query element vertex
+        * @param instanceVertex the instance vertex
+        * @param apiVer the api ver
+        * @return true - if a constraint was defined that has not been met by the passed instanceVertex
+        * @throws AAIException the AAI exception
+        */
+       public Boolean namedQueryConstraintSaysStop( String transId, String fromAppId,
+                       Vertex namedQueryElementVertex, Vertex instanceVertex, String apiVer )   
+                                 throws AAIException {
+               
+               // For each (if any) property-constraint defined for this named-query-element, we will evaluate if
+               // the constraint is met or not-met.  if there are constraints and any are not-met, then
+               // we return "true".
+               
+               if( namedQueryElementVertex == null ){
+                       String msg = " null namedQueryElementVertex passed to namedQueryConstraintSaysStop() ";
+                       throw new AAIException("AAI_6114", msg);
+               }
+               if( instanceVertex == null ){
+                       String msg = " null instanceVertex passed to namedQueryConstraintSaysStop() ";
+                       throw new AAIException("AAI_6114", msg);
+               }
+                               
+               Iterator<Vertex> constrPipe = this.traverseIncidentEdges(EdgeType.TREE, namedQueryElementVertex, "property-constraint");
+               if( constrPipe == null || !constrPipe.hasNext() ){
+                       // There's no "property-constraint" defined for this named-query-element.   No problem.
+                       return false;
+               }
+               
+               while( constrPipe.hasNext() ){
+                       Vertex constrVtx = (Vertex) constrPipe.next();
+                       // We found a property constraint that we will need to check
+                       String conType = constrVtx.<String>property("constraint-type").orElse(null);
+                       if( (conType == null) || conType.equals("")){
+                               String msg = " Bad property-constraint (constraint-type) found in Named Query definition. ";
+                               throw new AAIException("AAI_6133", msg);
+                       }
+                       String propName = constrVtx.<String>property("property-name").orElse(null);
+                       if( (propName == null) || propName.equals("")){
+                               String msg = " Bad property-constraint (property-name) found in Named Query definition. ";
+                               throw new AAIException("AAI_6133", msg);
+                       }
+                       String propVal = constrVtx.<String>property("property-value").orElse(null);
+                       if( (propVal == null) || propVal.equals("")){
+                               String msg = " Bad property-constraint (propVal) found in Named Query definition. ";
+                               throw new AAIException("AAI_6133", msg);
+                       }
+                       
+                       // See if that constraint is met or not
+                       String val = instanceVertex.<String>property(propName).orElse(null);
+                       if( val == null ){
+                               val = "";
+                       }
+                       
+                       if( conType.equals("EQUALS") ){
+                               if( !val.equals(propVal) ){
+                                       // This constraint was not met
+                                       return true;
+                               }
+                       }
+                       else if( conType.equals("NOT-EQUALS") ){
+                               if( val.equals(propVal) ){
+                                       // This constraint was not met
+                                       return true;
+                               }
+                       }
+                       else {
+                               String msg = " Bad property-constraint (constraint-type) found in Named Query definition. ";
+                               throw new AAIException("AAI_6133", msg);
+                       }
+               }
+                
+               return false;
+         
+       } // End of namedQueryConstraintSaysStop()
+
+       
+       /**
+        * Gets the named query extra data lookup.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param namedQueryElementVertex the named query element vertex
+        * @param instanceVertex the instance vertex
+        * @param apiVer the api ver
+        * @return HashMap of alternate properties to return for this element
+        * @throws AAIException the AAI exception
+        */
+       public Map<String,Object> getNamedQueryExtraDataLookup( String transId, String fromAppId,
+                       Vertex namedQueryElementVertex, Vertex instanceVertex, String apiVer )   
+                                 throws AAIException {
+               
+               // For each (if any) related-lookup defined for this named-query-element, we will go and
+               // and try to find it.  All the related-lookup data will get put in a hash and returned.
+               
+               if( namedQueryElementVertex == null ){
+                       String msg = " null namedQueryElementVertex passed to getNamedQueryExtraDataLookup() ";
+                       throw new AAIException("AAI_6114", msg);
+               }
+               if( instanceVertex == null ){
+                       String msg = " null instanceVertex passed to getNamedQueryExtraDataLookup() ";
+                       throw new AAIException("AAI_6114", msg);
+               }
+               
+               Map<String,Object> retHash = new HashMap<>();
+               
+               Iterator<Vertex> lookPipe = this.traverseIncidentEdges(EdgeType.TREE, namedQueryElementVertex, "related-lookup");
+               if( lookPipe == null || !lookPipe.hasNext() ){
+                       // There's no "related-lookup" defined for this named-query-element.   No problem.
+                       return retHash;
+               }
+               
+               while( lookPipe.hasNext() ){
+                       Vertex relLookupVtx = (Vertex) lookPipe.next();
+                       // We found a related-lookup record to try and use
+                       String srcProp = relLookupVtx.<String>property("source-node-property").orElse(null);
+                       if( (srcProp == null) || srcProp.equals("")){
+                               String msg = " Bad related-lookup (source-node-property) found in Named Query definition. ";
+                               throw new AAIException("AAI_6133", msg);
+                       }
+                       String targetNodeType = relLookupVtx.<String>property("target-node-type").orElse(null);
+                       if( (targetNodeType == null) || targetNodeType.equals("")){
+                               String msg = " Bad related-lookup (targetNodeType) found in Named Query definition. ";
+                               throw new AAIException("AAI_6133", msg);
+                       }
+                       String targetProp = relLookupVtx.<String>property("target-node-property").orElse(null);
+                       if( (targetProp == null) || targetProp.equals("")){
+                               String msg = " Bad related-lookup (target-node-property) found in Named Query definition. ";
+                               throw new AAIException("AAI_6133", msg);
+                       }
+                       
+                       List<String> propCollectList = new ArrayList<>();
+                       Iterator <VertexProperty<Object>> vpI = relLookupVtx.properties("property-collect-list");
+                       while( vpI.hasNext() ){
+                               propCollectList.add((String)vpI.next().value());
+                       }
+
+                       // Use the value from the source to see if we can find ONE target record using the value from the source
+                       String valFromInstance = instanceVertex.<String>property(srcProp).orElse(null);
+                       if( valFromInstance == null ){
+                               valFromInstance = "";
+                       }
+                       
+                       Map<String,Object> propHash = new HashMap<String,Object>();
+                       propHash.put(targetProp, valFromInstance);
+                       
+                       Optional<Vertex> result = dbMethHelper.locateUniqueVertex(targetNodeType, propHash);
+                       if (!result.isPresent()) {
+                               throw new AAIException("AAI_6114", "No Node of type " + targetNodeType + " found for properties");
+                       }
+                       Vertex tmpVtx = result.get();
+                       // Pick up the properties from the target vertex that they wanted us to get
+                       for( int j = 0; j < propCollectList.size(); j++ ){
+                               String tmpPropName = propCollectList.get(j);
+                               Object valObj = tmpVtx.<Object>property(tmpPropName).orElse(null);
+                               String lookupKey = targetNodeType + "." + tmpPropName;
+                               retHash.put(lookupKey, valObj);
+                               
+                       }
+               }
+                
+               return retHash;
+         
+       } // End of getNamedQueryExtraDataLookup()
+
+       /**
+        * Collect NQ element hash.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param thisLevelElemVtx the element verrtx for this level 
+        * @param incomingTrail the incoming trail -- trail of nodeTypes that got us here (this nq-element vertex) from the top
+        * @param currentHash the current hash
+     * @param Map that got us to this point (that we will use as the base of the map we will return)
+        * @param vidsTraversed the vids traversed -- ArrayList of vertexId's that we traversed to get to this point
+        * @param levelCounter the level counter
+        * @return HashMap of all widget-points on a namedQuery topology with the value being the "named-query-element-uuid" for that spot.
+        * @throws AAIException the AAI exception
+        */
+       public Map<String, String> collectNQElementHash( String transId, String fromAppId,
+                 Vertex thisLevelElemVtx, String incomingTrail, 
+                 Map<String,String> currentHash, ArrayList <String> vidsTraversed, 
+                 int levelCounter )   throws AAIException {
+       
+         levelCounter++;
+
+         Map<String, String> thisHash = new HashMap<>();
+         thisHash.putAll(currentHash);
+        
+         if( levelCounter > MAX_LEVELS ) {
+                 throw new AAIException("AAI_6125", "collectNQElementHash() has looped across more levels than allowed: " + MAX_LEVELS + ". "); 
+         }
+         String thisGuysTrail = "";
+         String thisElemVid = thisLevelElemVtx.id().toString();
+        
+         // Find out what widget (and thereby what aai-node-type) this element represents.
+         String thisElementNodeType = getNqElementWidgetType( transId, fromAppId,  thisLevelElemVtx, incomingTrail );
+         
+         if( incomingTrail == null || incomingTrail.equals("") ){
+                 // This is the first one
+                 thisGuysTrail = thisElementNodeType;
+         }
+         else {
+                 thisGuysTrail = incomingTrail + "|" + thisElementNodeType;
+         }
+         vidsTraversed.add(thisElemVid);
+         
+         String nqElementUuid = thisLevelElemVtx.<String>property("named-query-element-uuid").orElse(null);
+         if( nqElementUuid == null || nqElementUuid.equals("") ){
+                 String msg = " named-query element UUID not found at trail = [" + incomingTrail + "].";
+                 throw new AAIException("AAI_6133", msg);
+         }
+         thisHash.put(thisGuysTrail, nqElementUuid ); 
+         
+         //  Now go "down" and look at the sub-elements pointed to so we can get their data.
+         Iterator<Vertex> vertI = this.traverseIncidentEdges(EdgeType.TREE, thisLevelElemVtx, "named-query-element");
+         while( vertI != null && vertI.hasNext() ){
+                 Vertex tmpVert = vertI.next();
+                 String vid = tmpVert.id().toString();
+                 Map<String,Object> elementHash = new HashMap<String, Object>();
+                 
+                 String connectToType = tmpVert.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                 if( connectToType != null && connectToType.equals("named-query-element") ){
+                         // This is what we would expect
+                         elementHash.put(vid, tmpVert);
+                 }
+                 else {
+                         String msg = " named query element has [connectedTo] edge to improper nodeType= [" 
+                                         + connectToType + "] trail = [" + incomingTrail + "].";
+                         throw new AAIException("AAI_6133", msg);
+                 }
+                 for( Map.Entry<String, Object> entry : elementHash.entrySet() ){
+                         Vertex elVert = (Vertex)(entry.getValue());
+                         String tmpElVid = elVert.id().toString();
+                         if( !vidsTraversed.contains(tmpElVid) ){
+                                 // This is one we would like to use - so we'll recursively get it's result set to add to ours
+                                 Map<String, String> tmpHash = collectNQElementHash( transId, fromAppId, 
+                                                       elVert, thisGuysTrail, currentHash, vidsTraversed, levelCounter);
+                                 thisHash.putAll(tmpHash);
+                         }
+                 }             
+         }
+         return thisHash;
+         
+       } // End of collectNQElementHash()
+       
+
+       /**
+        * Collect delete key hash.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param thisLevelElemVtx the element vertex at this level
+        * @param incomingTrail the incoming trail -- trail of nodeTypes that got us here (this vertex) from the top
+        * @param currentHash the current hash
+     * @param Map that got us to this point (that we will use as the base of the map we will return)
+        * @param vidsTraversed the vids traversed ---- ArrayList of vertexId's that we traversed to get to this point
+        * @param levelCounter the level counter
+        * @param dbMaps the db maps
+        * @param modConstraintHash the mod constraint hash
+        * @param overRideModelId the over ride model id
+        * @param overRideModelVersionId the over ride model version id
+        * @return HashMap of all widget-points on a model topology with the value being the "newDataDelFlag" for that spot.
+        * @throws AAIException the AAI exception
+        */
+       public Map<String, String> collectDeleteKeyHash( String transId, String fromAppId,
+                 Vertex thisLevelElemVtx, String incomingTrail, 
+                 Map<String,String> currentHash, ArrayList <String> vidsTraversed, 
+                 int levelCounter, DbMaps dbMaps, Map<String, Vertex> modConstraintHash,
+                 String overRideModelId, String overRideModelVersionId )   
+                                 throws AAIException {
+       
+         levelCounter++;
+
+         Map<String, String> thisHash = new HashMap<>();
+         thisHash.putAll(currentHash);
+        
+         if( levelCounter > MAX_LEVELS ) {
+                 throw new AAIException("AAI_6125", "collectDeleteKeyHash() has looped across more levels than allowed: " + MAX_LEVELS + ". "); 
+         }
+         String thisGuysTrail = "";
+         String thisElemVid = thisLevelElemVtx.id().toString();
+         Map<String, Vertex> modConstraintHash2Use = null;
+         
+         // If this element represents a resource or service model, then we will replace this element with 
+         //    the "top" element of that resource or service model.  That model-element already points to its
+         //    topology, so it will graft in that model's topology.   
+         // EXCEPT - if this element has "linkage-points" defined, then we need to do some extra
+         //     processing for how we join to that model and will not try to go any "deeper".
+         List<String> linkagePtList = new ArrayList<>();
+         Iterator <VertexProperty<Object>> vpI = thisLevelElemVtx.properties("linkage-points");
+         //DEBUG -- AAI-8002 
+         // I am not sure why, but since "linkage-points" is an xml-element-wrapper in the OXM definition, 
+         // we get back the whole array of Strings in one String - but still use the "vtx.properties()" to
+         // get it - but only look at the first thing returned by the iterator.
+         if( vpI.hasNext() ){
+                 String tmpLinkageThing = (String)vpI.next().value();
+                 linkagePtList = makeSureItsAnArrayList( tmpLinkageThing );
+         }   
+                 
+         if( linkagePtList != null && !linkagePtList.isEmpty() ){
+                 // Whatever this element is - we are connecting to it via a linkage-point
+                 // We will figure out what to do and then return without going any deeper
+                 String elemFlag = thisLevelElemVtx.<String>property("new-data-del-flag").orElse(null);
+                 
+                 Set<String> linkageConnectNodeTypes = getLinkageConnectNodeTypes( linkagePtList );
+                 Iterator <?> linkNtIter = linkageConnectNodeTypes.iterator();
+                 String incTrail = "";
+                 if( incomingTrail != null &&  !incomingTrail.equals("") ){
+                         incTrail = incomingTrail + "|";
+                 }
+                 
+                 while( linkNtIter.hasNext() ){
+                         // The 'trail' (or trails) for this element should just be the to the first-contact on the linkage point
+                         String linkTrail = incTrail + linkNtIter.next();
+                         Boolean alreadyTaggedFalse = false;
+                         if( thisHash.containsKey(linkTrail) && thisHash.get(linkTrail).equals("F") ){
+                                 // some other path with a matching trail has the deleteFlag set to "F", so we do not want
+                                 // to override that since our model code only uses nodeTypes to know where it is - and we
+                                 // would rather do less deleting than needed instead of too much deleting.
+                                 alreadyTaggedFalse = true;
+                         }
+                         if( elemFlag != null && elemFlag.equals("T") && !alreadyTaggedFalse ){
+                                 // This trail should be marked with an "T"
+                                 thisHash.put(linkTrail, "T");
+                         }
+                         else {
+                                 thisHash.put(linkTrail, "F");
+                         }
+                 }
+                 return thisHash;
+         }
+  
+         // ----------------------------------------------------------------------------
+         // If we got to here, then this was not an element that used a linkage-point 
+         // ----------------------------------------------------------------------------
+         
+         // Find out what widget-model (and thereby what aai-node-type) this element represents.
+         // Even if this element is pointing to a service or resource model, it must have a
+         // first element which is a single widget-type model.  
+         String thisElementNodeType = getModElementWidgetType( thisLevelElemVtx, incomingTrail );
+         String firstElementModelInfo = "";
+
+         vidsTraversed.add(thisElemVid);
+         Vertex elementVtxForThisLevel = null;
+         Vertex thisElementsModelVerVtx = getModelVerThatElementRepresents( thisLevelElemVtx, incomingTrail );
+         Vertex thisElementsModelVtx = getModelGivenModelVer( thisElementsModelVerVtx, incomingTrail );
+         String modType = getModelTypeFromModel( thisElementsModelVtx, incomingTrail );
+         String subModelFirstModInvId = thisElementsModelVtx.<String>property("model-invariant-id").orElse(null);
+         String subModelFirstVerId = thisElementsModelVerVtx.<String>property("model-version-id").orElse(null);
+         if( modType.equals("widget") ){
+                 if( overRideModelId != null && !overRideModelId.equals("") ){
+                         // Note - this is just to catch the correct model for the TOP node in a model since
+                         //    it will have an element which will always be a widget even though the model
+                         //    could be a resource or service model.
+                         firstElementModelInfo = "," + overRideModelId + "," + overRideModelVersionId;
+                 }
+         }     
+         else if( nodeTypeSupportsPersona(thisElementNodeType, dbMaps) ){
+                 firstElementModelInfo = "," + subModelFirstModInvId + "," + subModelFirstVerId;
+         }
+                         
+         if( incomingTrail.equals("") ){
+                 // This is the first one
+                 thisGuysTrail = thisElementNodeType + firstElementModelInfo;
+         }
+         else {
+                 thisGuysTrail = incomingTrail + "|" + thisElementNodeType  + firstElementModelInfo;
+         }
+         
+         String tmpFlag = "F";
+         Boolean stoppedByASvcOrResourceModelElement = false;
+         if( modType.equals("widget") ){
+                 elementVtxForThisLevel = thisLevelElemVtx;
+                 // For the element-model for the widget at this level, record it's delete flag 
+                 tmpFlag = elementVtxForThisLevel.<String>property("new-data-del-flag").orElse(null);
+         }
+         else {
+                 // For an element that is referring to a resource or service model, we replace 
+             // this element with the "top" element for that resource/service model so that the
+                 // topology of that resource/service model will be included in this topology.
+                 String modelVerId = thisElementsModelVerVtx.<String>property("model-version-id").orElse(null);
+                 if( subModelFirstModInvId == null || subModelFirstModInvId.equals("") 
+                                 || subModelFirstVerId == null || subModelFirstVerId.equals("") ){
+                         throw new AAIException("AAI_6132", "Bad Model Definition: Bad model-invariant-id or model-version-id.  Model-version-id = " +
+                                 modelVerId + ", at [" + incomingTrail + "]");
+                 }
+                 
+                 // BUT --  if the model-element HERE at the resource/service level does NOT have 
+                 //    it's new-data-del-flag set to "T", then we do not need to go down into the 
+                 //    sub-model looking for delete-able things.
+
+                 tmpFlag = thisLevelElemVtx.<String>property("new-data-del-flag").orElse(null);
+                 elementVtxForThisLevel = getTopElementForSvcOrResModelVer(thisElementsModelVerVtx, thisGuysTrail);
+                 if( tmpFlag != null && tmpFlag.equals("T") ){
+                         modConstraintHash2Use = getModConstraintHash( thisLevelElemVtx, modConstraintHash );
+                 }
+                 else {
+                         stoppedByASvcOrResourceModelElement = true;
+                 }
+                 // For the element-model for the widget at this level, record it's delete flag 
+                 tmpFlag = elementVtxForThisLevel.<String>property("new-data-del-flag").orElse(null);
+         }
+         
+         String flag2Use = "F";  // by default we'll use "F" for the delete flag
+         if( ! stoppedByASvcOrResourceModelElement ){
+                 // Since we haven't been stopped by a resource/service level "F", we can look at the lower level flag
+                 if( thisHash.containsKey(thisGuysTrail) ){
+                         // We've seen this spot in the topology before - do not override the delete flag if the older one is "F"
+                         // We will only over-ride it if the old one was "T" and the new one is "F" (anything but "T")
+                         String oldFlag = thisHash.get(thisGuysTrail);
+                         if( oldFlag.equals("T") && (tmpFlag != null) && tmpFlag.equals("T") ){
+                                 // The old flag was "T" and the new flag is also "T"
+                                 flag2Use = "T";
+                         }
+                         else {
+                                 // the old flag was not "F" - so don't override it
+                                 flag2Use = "F";
+                         }
+                 }
+                 else if( (tmpFlag != null) && tmpFlag.equals("T") ){
+                         // We have not seen this one, so we can set it to "T" if that's what it is.
+                         flag2Use = "T";
+                 }
+         }
+         
+         thisHash.put(thisGuysTrail, flag2Use); 
+         if( ! stoppedByASvcOrResourceModelElement ){
+                 // Since we haven't been stopped by a resource/service level "F", we will continue to
+                 //     go "down" and look at the elements pointed to so we can get their data.
+                 Iterator<Vertex> vertI = this.traverseIncidentEdges(EdgeType.TREE, elementVtxForThisLevel, "model-element", "constrained-element-set");
+                  while( vertI != null && vertI.hasNext() ){
+                         Vertex tmpVert = vertI.next();
+                         String vid = tmpVert.id().toString();
+                         Map<String,Object> elementHash = new HashMap<String, Object>();
+                         
+                         String connectToType = tmpVert.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                         if( connectToType != null && connectToType.equals("model-element") ){
+                                 // A nice, regular old model-element
+                                 elementHash.put(vid, tmpVert);
+                         }
+                         else if( (connectToType != null) && connectToType.equals("constrained-element-set") ){
+                                 // translate the constrained-element-set into a hash of model-element Vertex's
+                                 String constrainedElementSetUuid = tmpVert.<String>property("constrained-element-set-uuid").orElse(null);
+                                 if( (modConstraintHash2Use != null) && modConstraintHash2Use.containsKey(constrainedElementSetUuid) ){
+                                         // This constrained-element-set is being superseded by a different one
+                                         Vertex replacementConstraintVert = modConstraintHash.get(constrainedElementSetUuid);
+                                         elementHash = getNextStepElementsFromSet( replacementConstraintVert );
+                                         // Now that we've found and used the replacement constraint, we don't need to carry it along any farther
+                                         modConstraintHash.remove(constrainedElementSetUuid);
+                                 }
+                                 else {
+                                         elementHash = getNextStepElementsFromSet( tmpVert );    
+                                 }
+                         }
+                         else {
+                                 String msg = " model-element has [connectedTo] edge to improper nodeType= [" 
+                                                 + connectToType + "] trail = [" + incomingTrail + "].";
+                                 throw new AAIException("AAI_6132", msg);
+                         }
+                         
+                         for( Map.Entry<String, Object> entry : elementHash.entrySet() ){
+                                 Vertex elVert = (Vertex)(entry.getValue());
+                                 String tmpElVid = elVert.id().toString();
+                                 String tmpElNT = getModElementWidgetType( elVert, thisGuysTrail );
+                                 check4EdgeRule(tmpElNT, thisElementNodeType, dbMaps);
+                                 if( !vidsTraversed.contains(tmpElVid) ){
+                                         // This is one we would like to use - so we'll recursively get it's result set to add to ours
+                                         Map<String, String> tmpHash = collectDeleteKeyHash( transId, fromAppId, 
+                                                               elVert, thisGuysTrail, 
+                                                               currentHash, vidsTraversed, levelCounter, dbMaps, modConstraintHash2Use,
+                                                               "", "" );
+                                         thisHash.putAll(tmpHash);
+                                 }
+                         }             
+                 }
+         }
+         return thisHash;
+         
+       } // End of collectDeleteKeyHash()
+       
+       
+       /**
+        * Gets the linkage connect node types.
+        *
+        * @param linkagePtList the linkage pt list
+        * @return the linkage connect node types
+        * @throws AAIException the AAI exception
+        */
+       public Set<String> getLinkageConnectNodeTypes(List<String> linkagePtList )
+                         throws AAIException {
+               // linkage points are a path from the top of a model to where we link in.  
+               // This method wants to just bring back a list of distinct last items.  
+               // Ie: for the input with these two:  "pserver|lag-link|l-interface" and "pserver|p-interface|l-interface"
+               //   it would just return a single item, "l-interface" since both linkage points end in that same node-type.
+               
+               Set<String> linkPtSet = new HashSet<>();
+               
+               if( linkagePtList == null ){
+                       String detail = " Bad (null) linkagePtList passed to getLinkageConnectNodeTypes() ";
+                       throw new AAIException("AAI_6125", detail); 
+               }
+               
+               for( int i = 0; i < linkagePtList.size(); i++ ){
+                       String [] trailSteps = linkagePtList.get(i).split("\\|");
+                       if( trailSteps == null || trailSteps.length == 0 ){
+                               String detail = " Bad incomingTrail passed to getLinkageConnectNodeTypes(): [" + linkagePtList + "] ";
+                               throw new AAIException("AAI_6125", detail); 
+                       }
+                       String lastStepNT = trailSteps[trailSteps.length - 1];
+                       linkPtSet.add(lastStepNT);
+               }
+               
+               return linkPtSet;
+       
+       }// End getLinkageConnectNodeTypes()
+       
+       
+       /**
+        * Collect topology for model-ver.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param modelElement vertex to collect for
+        * @param incomingTrail the incoming trail -- trail of nodeTypes/personaInfo that got us here (this vertex) from the top
+        * @param currentMap the current map -- map that got us to this point (that we will use as the base of the map we will return)
+        * @param vidsTraversed the vids traversed -- ArrayList of vertexId's that we traversed to get to this point
+        * @param levelCounter the level counter
+        * @param dbMaps the db maps
+        * @param modConstraintHash the mod constraint hash
+        * @param overRideModelInvId the override model-invariant-id
+        * @param overRideModelVersionId the override model-version-id
+        * @return Map of the topology
+        * @throws AAIException the AAI exception
+        */
+       public Multimap<String, String> collectTopology4ModelVer( String transId, String fromAppId,
+                 Vertex thisLevelElemVtx, String incomingTrail, 
+                 Multimap <String,String> currentMap, List<String> vidsTraversed, 
+                 int levelCounter, DbMaps dbMaps, Map<String, Vertex> modConstraintHash,
+                 String overRideModelInvId, String overRideModelVersionId )   
+                                 throws AAIException {
+       
+         levelCounter++;
+
+         Multimap <String, String> thisMap = ArrayListMultimap.create();
+         thisMap.putAll(currentMap);
+        
+         if( levelCounter > MAX_LEVELS ) {
+                 throw new AAIException("AAI_6125", "collectTopology4ModelVer() has looped across more levels than allowed: " + MAX_LEVELS + ". "); 
+         }
+         String thisGuysTrail = "";
+         String thisElemVid = thisLevelElemVtx.id().toString();
+         Map<String, Vertex> modConstraintHash2Use = null;
+         // If this element represents a resource or service model, then we will replace this element with 
+         // the "top" element of that resource or service model.  That model-element already points to its
+         // topology, so it will graft in that model's topology.   
+         // EXCEPT - if this element defines "linkage-points" defined, then we need to do some extra
+         //     processing for how we join to that model.
+       
+         // Find out what widget-model (and thereby what aai-node-type) this element represents.
+         // Even if this element is pointing to a service or resource model, it must have a
+         // first element which is a single widget-type model. 
+         String firstElementModelInfo = "";
+         String thisElementNodeType = getModElementWidgetType( thisLevelElemVtx, incomingTrail );
+         if( nodeTypeSupportsPersona(thisElementNodeType, dbMaps) && overRideModelInvId != null && !overRideModelInvId.equals("") ){
+                 firstElementModelInfo = "," + overRideModelInvId + "," + overRideModelVersionId;
+         }
+         
+         Vertex elementVtxForThisLevel = null;
+         Vertex thisElementsModelVerVtx = getModelVerThatElementRepresents( thisLevelElemVtx, incomingTrail );
+         String subModelFirstModInvId = "";
+         String subModelFirstModVerId = "";
+         String modInfo4Trail = "";
+         String modType = getModelTypeFromModelVer( thisElementsModelVerVtx, incomingTrail );
+         if( modType.equals("resource") || modType.equals("service") ){
+                 // For an element that is referring to a resource or service model, we replace this
+             // this element with the "top" element for that resource/service model so that the
+                 // topology of that resource/service model gets included in this topology.
+                 // -- Note - since that top element of a service or resource model will point to a widget model, 
+                 //    we have to track what modelId/version it really maps so we can make our recursive call
+                 Vertex thisElementsModelVtx = getModelGivenModelVer(thisElementsModelVerVtx, incomingTrail);
+                 subModelFirstModInvId = thisElementsModelVtx.<String>property("model-invariant-id").orElse(null);
+                 subModelFirstModVerId = thisElementsModelVerVtx.<String>property("model-version-id").orElse(null);
+                 
+                 if( nodeTypeSupportsPersona(thisElementNodeType, dbMaps) ){
+                               modInfo4Trail = "," + subModelFirstModInvId + "," + subModelFirstModVerId;
+                 }
+                 String modelVerId = thisElementsModelVerVtx.<String>property("model-version-id").orElse(null);
+                 if( subModelFirstModInvId == null || subModelFirstModInvId.equals("") || subModelFirstModVerId == null || subModelFirstModVerId.equals("") ){
+                         throw new AAIException("AAI_6132", "Bad Model Definition: Bad model-invariant-id or model-version-id.  Model-ver-id = " + modelVerId);
+                 }
+
+                 elementVtxForThisLevel = getTopElementForSvcOrResModelVer(thisElementsModelVerVtx,  incomingTrail);  
+                 modConstraintHash2Use = getModConstraintHash( thisLevelElemVtx, modConstraintHash );
+         }
+         else {
+                 elementVtxForThisLevel = thisLevelElemVtx;
+         }
+         
+         if( incomingTrail.equals("") ){
+                 // This is the first one
+                 thisGuysTrail = thisElementNodeType + firstElementModelInfo;
+         }
+         else {
+                 thisGuysTrail = incomingTrail + "|" + thisElementNodeType + modInfo4Trail;
+         }
+         
+         // We only want to ensure that a particular element does not repeat on a single "branch".
+         // It could show up on other branches in the case where it is a sub-model which is being
+         // used in more than one place.
+         //
+         List<String> thisTrailsVidsTraversed = new ArrayList <String>();
+         thisTrailsVidsTraversed.addAll(vidsTraversed);
+         thisTrailsVidsTraversed.add(thisElemVid);
+         
+         // Look at the elements pointed to at this level and add on their data
+         Iterator<Vertex> vertI = this.traverseIncidentEdges(EdgeType.TREE, elementVtxForThisLevel, "model-element", "constrained-element-set");
+
+          while( vertI != null && vertI.hasNext() ){
+                 Vertex tmpVert = vertI.next();
+                 String vid = tmpVert.id().toString();
+                 Map<String,Object> elementHash = new HashMap<String, Object>();
+                 String connectToType = tmpVert.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                 if( connectToType != null && connectToType.equals("model-element") ){
+                         // A nice, regular old model-element
+                         elementHash.put(vid, tmpVert);
+                 }
+                 else if( (connectToType != null) && connectToType.equals("constrained-element-set") ){
+                         // translate the constrained-element-set into a hash of model-element Vertex's
+                         String constrainedElementSetUuid = tmpVert.<String>property("constrained-element-set-uuid").orElse(null);
+                         if( (modConstraintHash2Use != null) && modConstraintHash2Use.containsKey(constrainedElementSetUuid) ){
+                                 // This constrained-element-set is being superseded by a different one
+                                 Vertex replacementConstraintVert = modConstraintHash.get(constrainedElementSetUuid);
+                                 elementHash = getNextStepElementsFromSet( replacementConstraintVert );
+                                 // Now that we've found and used the replacement constraint, we don't need to carry it along any farther
+                                 modConstraintHash.remove(constrainedElementSetUuid);
+                         }
+                         else {
+                                 elementHash = getNextStepElementsFromSet( tmpVert );    
+                         }
+                 }
+                 else {
+                         String msg = " model element has [connectedTo] edge to improper nodeType= [" 
+                                         + connectToType + "] trail = [" + incomingTrail + "].";
+                         throw new AAIException("AAI_6132", msg);
+                 }
+                 
+                 for( Map.Entry<String, Object> entry : elementHash.entrySet() ){
+                         Vertex elVert = (Vertex)(entry.getValue());
+                         String tmpElVid = elVert.id().toString();
+                         String tmpElNT = getModElementWidgetType( elVert, thisGuysTrail );
+                         String tmpElStepName = getModelElementStepName( elVert, thisGuysTrail, dbMaps );
+                         
+                         List<String> linkagePtList = new ArrayList <String>();
+                         Iterator <VertexProperty<Object>> vpI = elVert.properties("linkage-points");
+                         //DEBUG -- AAI-8002 
+                         // I am not sure why, but since "linkage-points" is an xml-element-wrapper in the OXM definition, 
+                         // we get back the whole array of Strings in one String - but still use the "vtx.properties()" to
+                         // get it - but only look at the first thing returned by the iterator.
+                         if( vpI.hasNext() ){
+                                 String tmpLinkageThing = (String)vpI.next().value();
+                                 linkagePtList = makeSureItsAnArrayList( tmpLinkageThing );
+                         } 
+                 
+                         if( linkagePtList != null && !linkagePtList.isEmpty() ){
+                                 // This is as far as we can go, we will use the linkage point info to define the 
+                                 // rest of this "trail" 
+                                 for( int i = 0; i < linkagePtList.size(); i++ ){
+                                         Multimap<String, String> tmpMap = collectTopology4LinkagePoint( transId, fromAppId,  
+                                                               linkagePtList.get(i), thisGuysTrail, currentMap, dbMaps);
+                                         thisMap.putAll(tmpMap);
+                                 }
+                         }
+                         else {
+                                 check4EdgeRule(tmpElNT, thisElementNodeType, dbMaps);
+                                 thisMap.put(thisGuysTrail, tmpElStepName);
+                                 if( !thisTrailsVidsTraversed.contains(tmpElVid) ){
+                                         // This is one we would like to use - so we'll recursively get it's result set to add to ours
+                                         Multimap<String, String> tmpMap = collectTopology4ModelVer( transId, fromAppId, 
+                                                               elVert, thisGuysTrail, 
+                                                               currentMap, thisTrailsVidsTraversed, levelCounter, 
+                                                               dbMaps, modConstraintHash2Use, subModelFirstModInvId, subModelFirstModVerId );
+                                         thisMap.putAll(tmpMap);
+                                 }
+                                 else {
+                                         String modelElementUuid = elVert.<String>property("model-element-uuid").orElse(null);
+                                         String msg = "Bad Model Definition: looping model-element (model-element-uuid = [" +
+                                                         modelElementUuid + "]) found trying to add step: [" + tmpElStepName + "], " +
+                                                         " on trail = [" + thisGuysTrail + "]. ";
+                                         System.out.println( msg );
+                                         throw new AAIException("AAI_6132", msg);
+                                 }       
+                         }  
+                 }             
+         }
+          
+         return thisMap;
+         
+       } // End of collectTopology4ModelVer()
+       
+       
+       /**
+        * Check 4 edge rule.
+        *
+        * @param nodeTypeA the node type A
+        * @param nodeTypeB the node type B
+        * @param dbMaps the db maps
+        * @throws AAIException the AAI exception
+        */
+       public void check4EdgeRule( String nodeTypeA, String nodeTypeB, DbMaps dbMaps ) throws AAIException {
+               // Throw an exception if there is no defined edge rule for this combination of nodeTypes in DbEdgeRules.
+               
+               final EdgeRules edgeRules = EdgeRules.getInstance();
+               
+               if( !edgeRules.hasEdgeRule(nodeTypeA, nodeTypeB)  
+                               &&  !edgeRules.hasEdgeRule(nodeTypeB, nodeTypeA) ){
+                       // There's no EdgeRule for this -- find out if one of the nodeTypes is invalid or if
+                       // they are valid, but there's just no edgeRule for them.
+                       if( ! dbMaps.NodeProps.containsKey(nodeTypeA) ){
+                               String emsg = " Unrecognized nodeType aa [" + nodeTypeA + "]\n";
+                               throw new AAIException("AAI_6115", emsg); 
+                       }
+                       else if( ! dbMaps.NodeProps.containsKey(nodeTypeB) ){
+                               String emsg = " Unrecognized nodeType bb [" + nodeTypeB + "]\n";
+                               throw new AAIException("AAI_6115", emsg); 
+                       }
+                       else {
+                               String msg = " No Edge Rule found for this pair of nodeTypes (order does not matter) [" 
+                                         + nodeTypeA + "], [" + nodeTypeB + "].";
+                               throw new AAIException("AAI_6120", msg);
+                       }
+               }
+               
+       }
+       
+    
+       /**
+        * Collect topology 4 linkage point.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param linkagePointStr -- Note it is in reverse order from where we connect to it.
+        * @param incomingTrail -- trail of nodeTypes that got us here (this vertex) from the top
+        * @param currentMap the current map -- that got us to this point (that we will use as the base of the map we will return)
+        * @param dbMaps the db maps
+        * @return Map of the topology
+        * @throws AAIException the AAI exception
+        */
+       public Multimap<String, String> collectTopology4LinkagePoint( String transId, String fromAppId, 
+                 String linkagePointStrVal, String incomingTrail, Multimap <String,String> currentMap, DbMaps dbMaps )   
+                                 throws AAIException {
+
+         Multimap <String, String> thisMap = ArrayListMultimap.create();
+         thisMap.putAll(currentMap);
+         String thisGuysTrail = incomingTrail;
+         
+         // NOTE - "trails" can have multiple parts now since we track persona info for some.
+         //      We just want to look at the node type info - which would be the piece
+         //      before any commas (if there are any).
+        
+         String [] trailSteps = thisGuysTrail.split("\\|");
+         if( trailSteps == null || trailSteps.length == 0 ){
+                 throw new AAIException("AAI_6125", "Bad incomingTrail passed to collectTopology4LinkagePoint(): [" + incomingTrail + "] "); 
+         }
+         String lastStepString = trailSteps[trailSteps.length - 1];
+         String [] stepPieces = lastStepString.split(",");
+         String lastStepNT = stepPieces[0];
+         
+         // It is assumed that the linkagePoint string will be a pipe-delimited string where each
+         // piece is an AAIProperties.NODE_TYPE.  For now, the first thing to connect to is what is on the farthest right.
+         // Example:  linkagePoint =  "pserver|p-interface|l-interface"   would mean that we're connecting to the l-interface
+         //      but that after that, we connect to a p-interface followed by a pserver.
+         // It might have been more clear to define it in the other direction, but for now, that is it. (16-07)
+         String linkagePointStr = linkagePointStrVal;
+         // --- DEBUG For AAI-8002 
+         // We are getting these with more than linkage thing in one string.  
+         //   Ie. "pserver|lag-interface|l-interface, pserver|p-interface|l-interface, vlan|l-interface"
+         linkagePointStr = linkagePointStr.replace("[",  "");
+         linkagePointStr = linkagePointStr.replace("]",  "");
+         linkagePointStr = linkagePointStr.replace(" ",  "");
+         
+         String [] linkage = linkagePointStr.split("\\,");
+         for( int x = 0; x < linkage.length; x++ ){
+                 lastStepNT = stepPieces[0]; 
+                 String thisStepNT = "";
+                 String [] linkageSteps = linkage[x].split("\\|");
+                 if( linkageSteps == null || linkageSteps.length == 0 ){
+                         throw new AAIException("AAI_6125", "Bad linkagePointStr passed to collectTopology4LinkagePoint(): [" + linkagePointStr + "] "); 
+                 }
+                 for( int i=(linkageSteps.length - 1); i >= 0; i-- ){
+                         thisStepNT = linkageSteps[i];
+                         check4EdgeRule(lastStepNT, thisStepNT, dbMaps);
+                         thisMap.put(thisGuysTrail, thisStepNT);
+                         thisGuysTrail = thisGuysTrail + "|" + thisStepNT;
+                         lastStepNT = thisStepNT;
+                 }
+         }
+         return thisMap;
+         
+       } // End of collectTopology4LinkagePoint()
+       
+   
+       /**
+        * Gets the next step elements from set.
+        *
+        * @param constrElemSetVtx the constr elem set vtx
+        * @return Hash of the set of model-elements this set represents
+        * @throws AAIException the AAI exception
+        */
+       public Map<String,Object> getNextStepElementsFromSet( Vertex constrElemSetVtx )   
+                                 throws AAIException {
+               // Take a constrained-element-set and figure out the total set of all the possible elements that it
+               // represents and return them as a Hash.
+         
+               Map<String,Object> retElementHash = new HashMap<String, Object>();
+       
+               if( constrElemSetVtx == null ){
+                         String msg = " getNextStepElementsFromSet() called with null constrElemSetVtx ";
+                         throw new AAIException("AAI_6125", msg);
+               }
+       
+               String constrNodeType = constrElemSetVtx.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+               String constrElemSetUuid = constrElemSetVtx.<String>property("constrained-element-set-uuid").orElse(null);
+               if( constrNodeType == null || !constrNodeType.equals("constrained-element-set") ){
+                         String msg = " getNextStepElementsFromSet() called with wrong type model: [" + constrNodeType + "]. ";
+                         throw new AAIException("AAI_6125", msg);
+               }
+               
+               ArrayList <Vertex>  choiceSetVertArray = new ArrayList<Vertex>();
+               Iterator<Vertex> vertI = this.traverseIncidentEdges(EdgeType.TREE, constrElemSetVtx, "element-choice-set");
+               int setCount = 0;
+               while( vertI != null && vertI.hasNext() ){
+                       Vertex choiceSetVertex = vertI.next();
+                       String constrSetType = choiceSetVertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                       if( constrSetType != null && constrSetType.equals("element-choice-set") ){
+                               choiceSetVertArray.add(choiceSetVertex);
+                               setCount++;
+                       }
+               }
+                       
+               if( setCount == 0 ){
+                         String msg = "No element-choice-set found under constrained-element-set-uuid = " + constrElemSetUuid;
+                         throw new AAIException("AAI_6132", msg);
+               }
+               
+               // Loop through each choice-set and grab the model-elements
+               for( int i = 0; i < setCount; i++ ){
+                       Vertex choiceSetVert = choiceSetVertArray.get(i);
+                       Iterator<Vertex> mVertI = this.traverseIncidentEdges(EdgeType.TREE, choiceSetVert, "model-element");
+                       int elCount = 0;
+                       while( mVertI != null && mVertI.hasNext() ){
+                               Vertex tmpElVertex = mVertI.next();
+                               String elNodeType = tmpElVertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                               if( elNodeType != null && elNodeType.equals("model-element") ){
+                                       String tmpVid = tmpElVertex.id().toString();
+                                       retElementHash.put(tmpVid, tmpElVertex);
+                                       elCount++;
+                               }
+                               else {
+                                       // unsupported node type found for this choice-set
+                                       String msg = "Unsupported nodeType (" + elNodeType 
+                                                       + ") found under choice-set under constrained-element-set-uuid = " + constrElemSetUuid;
+                                       throw new AAIException("AAI_6132", msg);
+                               }
+                       }
+                               
+                       if( elCount == 0 ){
+                                 String msg = "No model-elements found in choice-set under constrained-element-set-uuid = " + constrElemSetUuid;
+                                 throw new AAIException("AAI_6132", msg);
+                       }
+                       
+               }
+         return retElementHash;
+         
+       } // End of getNextStepElementsFromSet()
+       
+       
+       
+       /**
+        * Gen topo map 4 named Q.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param queryVertex the query vertex
+        * @param namedQueryUuid the named query uuid
+        * @return MultiMap of valid next steps for each potential query-element
+        * @throws AAIException the AAI exception
+        */
+       public Multimap<String, String> genTopoMap4NamedQ( String transId, String fromAppId, 
+                Vertex queryVertex, String namedQueryUuid )   
+                                 throws AAIException {
+         
+         if( queryVertex == null ){
+                 throw new AAIException("AAI_6125", "null queryVertex passed to genTopoMap4NamedQ()");
+         }
+         
+         Multimap <String, String> initialEmptyMap = ArrayListMultimap.create();
+         List<String> vidsTraversed = new ArrayList<>();
+         
+         Vertex firstElementVertex = null;
+         Iterator<Vertex> vertI = this.traverseIncidentEdges(EdgeType.TREE, queryVertex, "named-query-element");
+         int elCount = 0;
+         while( vertI != null && vertI.hasNext() ){
+                 elCount++;
+                 firstElementVertex = vertI.next();
+         }
+               
+         if( elCount > 1 ){
+                 throw new AAIException("AAI_6133", "Illegal query defined: More than one first element defined for = " + namedQueryUuid);
+         }
+         
+         if( firstElementVertex == null ){
+                 throw new AAIException("AAI_6114", "Could not find first query element = " + namedQueryUuid);
+         }
+       
+         Vertex modVtx = getModelThatNqElementRepresents( firstElementVertex, "" );
+         String modelType = getModelTypeFromModel( modVtx, "" );         
+         if( ! modelType.equals("widget") ){
+                 throw new AAIException("AAI_6133", "Bad Named Query Definition: First element must correspond to a widget type model.  Named Query UUID = " 
+                                 + namedQueryUuid);
+         }
+         
+         Multimap <String, String> collectedMap = collectTopology4NamedQ( transId, fromAppId, 
+                               firstElementVertex, "", 
+                               initialEmptyMap, vidsTraversed, 0);
+         
+         return collectedMap;
+         
+       } // End of genTopoMap4NamedQ()
+
+       
+    
+       /**
+        * Collect topology 4 named Q.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param thisLevelElemVtx the model element vertex for this level
+        * @param levelCounter the level counter
+        * @return resultSet
+        * @throws AAIException the AAI exception
+        */
+       public Multimap<String, String> collectTopology4NamedQ( String transId, String fromAppId,
+                 Vertex thisLevelElemVtx, String incomingTrail, 
+                 Multimap <String,String> currentMap, List<String> vidsTraversed, int levelCounter )   
+                                 throws AAIException {
+       
+         levelCounter++;
+
+         Multimap <String, String> thisMap = ArrayListMultimap.create();
+         thisMap.putAll(currentMap);
+        
+         String thisElemVid = thisLevelElemVtx.id().toString();
+         if( levelCounter > MAX_LEVELS ) {
+                 throw new AAIException("AAI_6125", "collectModelStructure() has looped across more levels than allowed: " + MAX_LEVELS + ". "); 
+         }
+         String thisGuysTrail = "";
+         
+         // find out what widget (and thereby what aai-node-type) this element represents
+         String thisElementNodeType = getNqElementWidgetType( transId, fromAppId, thisLevelElemVtx, incomingTrail );
+         
+         if( incomingTrail.equals("") ){
+                 // This is the first one
+                 thisGuysTrail = thisElementNodeType;
+         }
+         else {
+                 thisGuysTrail = incomingTrail + "|" + thisElementNodeType;
+         }
+         
+         vidsTraversed.add(thisElemVid);
+         
+         // Look at the elements pointed to at this level and add on their data
+         Iterator<Vertex> vertI = this.traverseIncidentEdges(EdgeType.TREE, thisLevelElemVtx, "named-query-element");
+         while( vertI != null && vertI.hasNext() ){
+                 Vertex tmpVert = vertI.next();
+                 String tmpVid = tmpVert.id().toString();
+                 String tmpElNT = getNqElementWidgetType( transId, fromAppId, tmpVert, thisGuysTrail );
+                 thisMap.put(thisGuysTrail, tmpElNT);
+                 if( !vidsTraversed.contains(tmpVid) ){
+                         // This is one we would like to use - so we'll recursively get it's result set to add to ours
+                         Multimap<String, String> tmpMap = collectTopology4NamedQ( transId, fromAppId, 
+                                               tmpVert, thisGuysTrail, 
+                                               currentMap, vidsTraversed, levelCounter);
+                         thisMap.putAll(tmpMap);
+                 }
+         }
+         
+         return thisMap;
+         
+       } // End of collectTopology4NamedQ()
+
+
+       /**
+        * Gets the model that NamedQuery element represents.
+        *
+        * @param elementVtx the NQ element vtx
+        * @param elementTrail the element trail
+        * @return the model that element represents
+        * @throws AAIException the AAI exception
+        */
+       public Vertex getModelThatNqElementRepresents( Vertex elementVtx, String elementTrail )
+               throws AAIException {
+               
+                 // Get the model that a named-query element represents
+                 Vertex modVtx = null;
+                 Iterator<Vertex> mvertI = this.traverseIncidentEdges(EdgeType.COUSIN, elementVtx, "model");
+                 int modCount = 0;
+                 while( mvertI != null && mvertI.hasNext() ){
+                         modCount++;
+                         modVtx = mvertI.next();
+                 }
+                       
+                 if( modCount > 1 ){
+                         String msg = "Illegal element defined: More than one model pointed to by a single named-query-element at [" +
+                                         elementTrail + "].";
+                         throw new AAIException("AAI_6125", msg);
+                 }
+                 
+                 if( modVtx == null ){
+                         String msg = "Bad named-query definition: Could not find model for element. ";
+                         if( !elementTrail.equals("") ){
+                                 msg = "Bad named-query definition: Could not find model for named-query-element at [" + elementTrail + "].";
+                         }
+                         throw new AAIException("AAI_6132", msg);
+                 }
+                 
+                 String nodeType = modVtx.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                 if( (nodeType != null) && nodeType.equals("model") ){
+                         return modVtx;
+                 }
+                 else {
+                         String msg = "Illegal Named Query element defined: expecting a 'model', but found 'isA' edge pointing to nodeType = " + 
+                                         nodeType + "] at [" +   elementTrail + "].";
+                         throw new AAIException("AAI_6125", msg);
+                 }       
+                   
+       }// getModelThatNqElementRepresents()
+       
+       
+       /**
+        * Gets the model-ver that element represents.
+        *
+        * @param elementVtx the element vtx
+        * @param elementTrail the element trail
+        * @return the model-ver that element represents
+        * @throws AAIException the AAI exception
+        */
+       public Vertex getModelVerThatElementRepresents( Vertex elementVtx, String elementTrail )
+               throws AAIException {
+               
+                 // Get the model-ver that an element represents
+                 Vertex modVerVtx = null;
+                 Iterator<Vertex> mvertI = this.traverseIncidentEdges(EdgeType.COUSIN, elementVtx, "model-ver");
+                 int modCount = 0;
+                 while( mvertI != null && mvertI.hasNext() ){
+                         modCount++;
+                         modVerVtx = mvertI.next();
+                 }
+                       
+                 if( modCount > 1 ){
+                         String msg = "Illegal element defined: More than one model pointed to by a single element at [" +
+                                         elementTrail + "].";
+                         throw new AAIException("AAI_6125", msg);
+                 }
+                 
+                 if( modVerVtx == null ){
+                         String msg = "Bad model definition: Could not find model-ver for model-element. ";
+                         if( !elementTrail.equals("") ){
+                                 msg = "Bad model definition: Could not find model-VER for model-element at [" + elementTrail + "].";
+                         }
+                         throw new AAIException("AAI_6132", msg);
+                 }
+                 
+                 String nodeType = modVerVtx.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                 if( (nodeType != null) && nodeType.equals("model-ver") ){
+                         return modVerVtx;
+                 }
+                 else {
+                         String msg = "Illegal model-element defined: expecting a 'model-ver', but found 'isA' edge pointing to nodeType = " + 
+                                         nodeType + "] at [" +   elementTrail + "].";
+                         throw new AAIException("AAI_6125", msg);
+                 }
+                   
+       }// getModelVerThatElementRepresents()
+       
+       
+       
+       /**
+        * Gets the model that is parent to model-ver node.
+        *
+        * @param modVerVtx the model-ver vtx
+        * @param elementTrail the element trail
+        * @return the model that element represents
+        * @throws AAIException the AAI exception
+        */
+       public Vertex getModelGivenModelVer( Vertex modVerVtx, String elementTrail )
+               throws AAIException {
+               
+               // Get the parent model for this "model-ver" node
+                 Vertex modVtx = null;
+                 Iterator<Vertex> mvertI = this.traverseIncidentEdges(EdgeType.TREE, modVerVtx, "model");
+                 int modCount = 0;
+                 while( mvertI != null && mvertI.hasNext() ){
+                         modCount++;
+                         modVtx = mvertI.next();
+                 }
+                       
+                 if( modCount > 1 ){
+                         String msg = "Illegal model-ver node defined: More than one model points to it with a 'has' edge [" +
+                                         elementTrail + "].";
+                         throw new AAIException("AAI_6125", msg);
+                 }
+                 
+                 if( modVtx == null ){
+                         String msg = "Bad model-ver node: Could not find parent model. ";
+                         if( !elementTrail.equals("") ){
+                                 msg = "Bad model-ver node: Could not find parent model. [" + elementTrail + "].";
+                         }
+                         throw new AAIException("AAI_6132", msg);
+                 }
+                 
+                 String nodeType = modVtx.<String>property(AAIProperties.NODE_TYPE).orElse(null);;
+                 if( (nodeType != null) && nodeType.equals("model") ){
+                         // Found what we were looking for.
+                         return modVtx;
+                 }
+                 else {
+                         // Something is amiss
+                         String msg = " Could not find parent model node for model-ver node at [" +
+                                         elementTrail + "].";
+                         throw new AAIException("AAI_6125", msg);
+                 }
+                   
+               
+       }// getModelGivenModelVer()
+       
+       
+                       
+       /**
+        * Gets the model type.
+        *
+        * @param modelVtx the model vtx
+        * @param elementTrail the element trail
+        * @return the model type
+        * @throws AAIException the AAI exception
+        */
+       public String getModelTypeFromModel( Vertex modelVtx, String elementTrail )
+               throws AAIException {
+                 
+               // Get the model-type from a model vertex
+               if( modelVtx == null ){
+                        String msg = " null modelVtx passed to getModelTypeFromModel() ";
+                        throw new AAIException("AAI_6114", msg);
+               }                 
+                
+               String modelType = modelVtx.<String>property("model-type").orElse(null);
+               if( (modelType == null) || modelType.equals("") ){
+                       String msg = "Could not find model-type for model encountered at [" + elementTrail + "].";
+                       throw new AAIException("AAI_6132", msg);
+               }
+               
+               if( !modelType.equals("widget") && !modelType.equals("resource") && !modelType.equals("service") ){
+                       String msg = "Unrecognized model-type, [" + modelType + "] for model pointed to by element at [" + elementTrail + "].";
+                       throw new AAIException("AAI_6132", msg);
+               }
+                 
+               return modelType; 
+               
+       }// getModelTypeFromModel()
+       
+       
+               
+       /**
+       * Gets the model type given model-ver
+       *
+       * @param modelVerVtx the model-ver vtx
+       * @param elementTrail the element trail
+       * @return the model type
+       * @throws AAIException the AAI exception
+       */
+       public String getModelTypeFromModelVer( Vertex modelVerVtx, String elementTrail )
+       throws AAIException {
+         
+       // Get the model-type given a model-ver vertex
+       if( modelVerVtx == null ){
+                String msg = " null modelVerVtx passed to getModelTypeFromModelVer() ";
+                throw new AAIException("AAI_6114", msg);
+       }                 
+        
+       Vertex modVtx = getModelGivenModelVer( modelVerVtx, elementTrail );
+       String modelType = modVtx.<String>property("model-type").orElse(null);
+       if( (modelType == null) || modelType.equals("") ){
+               String msg = "Could not find model-type for model encountered at [" + elementTrail + "].";
+               throw new AAIException("AAI_6132", msg);
+       }
+       
+       if( !modelType.equals("widget") && !modelType.equals("resource") && !modelType.equals("service") ){
+               String msg = "Unrecognized model-type, [" + modelType + "] for model pointed to by element at [" + elementTrail + "].";
+               throw new AAIException("AAI_6132", msg);
+       }
+         
+       return modelType; 
+       
+       }// getModelTypeFromModelVer()
+               
+               
+
+       /**
+        * Gets the model-element step name.
+        *
+        * @param elementVtx the model-element vtx
+        * @param elementTrail the element trail
+        * @param dbMaps the db maps
+        * @return the element step name
+        * @throws AAIException the AAI exception
+        */
+       public String getModelElementStepName( Vertex elementVtx, String elementTrail, DbMaps dbMaps)
+               throws AAIException {
+               
+               // Get the "step name"  for a model-element 
+               // Step names look like this for widget-models:   AAIProperties.NODE_TYPE
+               // Step names look like this for resource/service models: "aai-node-type,model-invariant-id,model-version-id"
+               // NOTE -- if the element points to a resource or service model, then we'll return the
+               //        widget-type of the first element (crown widget) for that model.
+               String thisElementNodeType = "?";
+               Vertex modVerVtx = getModelVerThatElementRepresents( elementVtx, elementTrail );
+               String modelType = getModelTypeFromModelVer( modVerVtx, elementTrail );
+               
+               if( modelType == null ){
+                       String msg = " could not determine modelType in getModelElementStepName().  elementTrail = [" + elementTrail + "].";
+                       throw new AAIException("AAI_6132", msg);
+               }
+                 
+               if( modelType.equals("widget") ){
+                       // NOTE: for models that have model-type = "widget", their "model-name" maps directly to aai-node-type 
+                       thisElementNodeType = modVerVtx.<String>property("model-name").orElse(null);
+                       if( (thisElementNodeType == null) || thisElementNodeType.equals("") ){
+                               String msg = "Could not find model-name for the widget model pointed to by element at [" + elementTrail + "].";
+                               throw new AAIException("AAI_6132", msg);
+                       }
+                       return thisElementNodeType;
+               }
+               else if( modelType.equals("resource") || modelType.equals("service") ){
+                       Vertex modVtx = getModelGivenModelVer( modVerVtx, elementTrail );
+                       String modInvId = modVtx.<String>property("model-invariant-id").orElse(null); 
+                       String modVerId = modVerVtx.<String>property("model-version-id").orElse(null);
+                       Vertex relatedTopElementModelVtx = getTopElementForSvcOrResModelVer( modVerVtx, elementTrail );
+                       Vertex relatedModelVtx = getModelVerThatElementRepresents( relatedTopElementModelVtx, elementTrail );
+                       thisElementNodeType = relatedModelVtx.<String>property("model-name").orElse(null);
+                       
+                       if( (thisElementNodeType == null) || thisElementNodeType.equals("") ){
+                               String msg = "Could not find model-name for the widget model pointed to by element at [" + elementTrail + "].";
+                               throw new AAIException("AAI_6132", msg);
+                       }
+                       
+                       String stepName = "";
+                       if( nodeTypeSupportsPersona(thisElementNodeType, dbMaps) ){
+                               // This nodeType that this resource or service model refers to does support persona-related fields, so
+                               // we will use model-invariant-id and model-version-id as part of the step name.
+                               stepName = thisElementNodeType + "," + modInvId + "," + modVerId;
+                       }
+                       else {
+                               stepName = thisElementNodeType;
+                       }
+                       return stepName;
+               }
+               else {
+                       String msg = " Unrecognized model-type = [" + modelType + "] pointed to by element at [" + elementTrail + "].";
+                       throw new AAIException("AAI_6132", msg);
+               }
+                 
+       }// getModelElementStepName()
+       
+       
+       
+       /**
+        * Node type supports persona.
+        *
+        * @param nodeType the node type
+        * @param dbMaps the db maps
+        * @return the boolean
+        * @throws AAIException the AAI exception
+        */
+       public Boolean nodeTypeSupportsPersona(String nodeType, DbMaps dbMaps)
+                       throws AAIException {
+               
+               if( nodeType == null || nodeType.equals("") ){
+                       return false;
+               }
+               
+               // Return true if this type of node supports the properties: "model-invariant-id-local" and "model-version-id-local"
+               if( ! dbMaps.NodeProps.containsKey(nodeType) ){
+                       String emsg = " Unrecognized nodeType [" + nodeType + "]\n";
+                       throw new AAIException("AAI_6115", emsg); 
+               }  
+               
+               Collection <String> props4ThisNT = dbMaps.NodeProps.get(nodeType);
+               if( !props4ThisNT.contains("model-invariant-id-local") || !props4ThisNT.contains("model-version-id-local") ){
+                       return false;
+               }
+               else {
+                       return true;
+               }
+               
+       }// nodeTypeSupportsPersona()
+       
+       
+       /**
+        * Gets a Named Query element's widget type.
+        *
+        * @param elementVtx the named-query element vtx
+        * @param elementTrail the element trail
+        * @return the element widget type
+        * @throws AAIException the AAI exception
+        */
+       public String getNqElementWidgetType( String transId, String fromAppId,
+                       Vertex elementVtx, String elementTrail )
+               throws AAIException {
+               
+               String thisNqElementWidgetType = "";
+               // Get the associated node-type for the model pointed to by a named-query-element.
+               // NOTE -- if the element points to a resource or service model, then we'll return the
+               //        widget-type of the first element (crown widget) for that model.
+               Vertex modVtx = getModelThatNqElementRepresents( elementVtx, elementTrail );
+               String modelType = getModelTypeFromModel( modVtx, elementTrail );
+               
+               if( modelType == null || !modelType.equals("widget") ){
+                       String emsg = " Model Type must be 'widget' for NamedQuery elements.  Found [" + modelType + "] at [" + 
+                                       elementTrail + "]\n";
+                       throw new AAIException("AAI_6132", emsg); 
+               }
+               else {
+                       // For a Widget model, the nodeType is just mapped to the model-element.model-name
+                       List<Vertex> modVerVtxArr =  getModVersUsingModel(transId, fromAppId, modVtx);
+                       if( modVerVtxArr != null && !modVerVtxArr.isEmpty() ){
+                               thisNqElementWidgetType = (modVerVtxArr.get(0)).<String>property("model-name").orElse(null);
+                       }
+                       if( thisNqElementWidgetType == null || thisNqElementWidgetType.equals("") ){
+                               String emsg = " Widget type could not be determined at [" + elementTrail + "]\n";
+                                       throw new AAIException("AAI_6132", emsg); 
+                       }
+                       else {
+                               return thisNqElementWidgetType;
+                       }
+               }
+               
+               
+       }// End  getNqElementWidgetType()
+       
+       
+       /**
+        * Gets a model-element's top widget type.
+        *
+        * @param elementVtx the model element vtx
+        * @param elementTrail the element trail
+        * @return the element widget type
+        * @throws AAIException the AAI exception
+        */
+       public String getModElementWidgetType( Vertex elementVtx, String elementTrail )
+               throws AAIException {
+               
+               // Get the associated node-type for the model-ver pointed to by a model-element.
+               // NOTE -- if the element points to a resource or service model, then we'll return the
+               //        widget-type of the first element (crown widget) for that model.
+               Vertex modVerVtx = getModelVerThatElementRepresents( elementVtx, elementTrail );
+               String thisElementNodeType = getModelVerTopWidgetType( modVerVtx, elementTrail );
+               return thisElementNodeType;
+                       
+       }// End  getModElementWidgetType()
+       
+       
+       /**
+        * Gets the node using unique identifier
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param nodeType the nodeType 
+        * @param idPropertyName the property name of the unique identifier
+        * @param uniqueIdVal the UUID value
+        * @return unique vertex found using UUID
+        * @throws AAIException the AAI exception
+        */
+       public Vertex getNodeUsingUniqueId( String transId, String fromAppId,
+                       String nodeType, String idPropertyName, String uniqueIdVal )
+               throws AAIException {
+               
+               // Given a unique identifier, get the Vertex 
+               if( uniqueIdVal == null || uniqueIdVal.equals("")  ){
+                       String emsg = " Bad uniqueIdVal passed to getNodeUsingUniqueId(): [" 
+                                       + uniqueIdVal + "]\n";
+                       throw new AAIException("AAI_6118", emsg); 
+               }
+               
+               if( idPropertyName == null || idPropertyName.equals("")  ){
+                       String emsg = " Bad idPropertyName passed to getNodeUsingUniqueId(): [" 
+                                       + idPropertyName + "]\n";
+                       throw new AAIException("AAI_6118", emsg); 
+               }               
+               
+               if( nodeType == null || nodeType.equals("")  ){
+                       String emsg = " Bad nodeType passed to getNodeUsingUniqueId(): [" 
+                                       + nodeType + "]\n";
+                       throw new AAIException("AAI_6118", emsg); 
+               }               
+               
+               Vertex uniqVtx = null;
+               Iterable <?> uniqVerts = null;
+               uniqVerts = engine.asAdmin().getReadOnlyTraversalSource().V().has(AAIProperties.NODE_TYPE,nodeType).has(idPropertyName,uniqueIdVal).toList();
+               if( uniqVerts == null ){
+                       String emsg = "Node could not be found for nodeType = [" + nodeType 
+                                       + "], propertyName = [" + idPropertyName  
+                                       + "], propertyValue = [" + uniqueIdVal  + "]\n";
+                       throw new AAIException("AAI_6114", emsg); 
+               }
+               else { 
+                       int count = 0;
+                       Iterator <?> uniqVertsIter = uniqVerts.iterator();
+                       if( !uniqVertsIter.hasNext() ){
+                               String emsg = "Node could not be found for nodeType = [" + nodeType 
+                                               + "], propertyName = [" + idPropertyName  
+                                               + "], propertyValue = [" + uniqueIdVal  + "]\n";
+                               throw new AAIException("AAI_6114", emsg); 
+                       }
+                       else {
+                               while( uniqVertsIter.hasNext() ){
+                                       count++;
+                                       uniqVtx = (Vertex) uniqVertsIter.next();
+                                       if( count > 1 ){
+                                               String emsg = "More than one node found for nodeType = [" + nodeType 
+                                                               + "], propertyName = [" + idPropertyName  
+                                                               + "], propertyValue = [" + uniqueIdVal  + "]\n";
+                                               throw new AAIException("AAI_6132", emsg); 
+                                       }
+                               }
+                       }
+               }
+               
+               return uniqVtx;
+       }// End getNodeUsingUniqueId()
+       
+       
+       /**
+        * Gets the model-ver nodes using name.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param modelName the model name
+        * @return the model-ver's that use this name
+        * @throws AAIException the AAI exception
+        */
+       public List<Vertex> getModelVersUsingName( String transId, String fromAppId,
+                       String modelName )
+               throws AAIException {
+               
+               // Given a "model-name", find the model-ver vertices that this maps to
+               if( modelName == null || modelName.equals("")  ){
+                       String emsg = " Bad modelName passed to getModelVersUsingName(): [" 
+                                       + modelName + "]\n";
+                       throw new AAIException("AAI_6118", emsg); 
+               }
+               
+               List<Vertex> retVtxArr = new ArrayList<>();
+               Iterator<Vertex> modVertsIter = this.engine.asAdmin().getReadOnlyTraversalSource().V().has(AAIProperties.NODE_TYPE,"model-ver").has("model-name",modelName);
+               if( !modVertsIter.hasNext() ){
+                       String emsg = "Model-ver record(s) could not be found for model-ver data passed.  model-name = [" + 
+                                       modelName + "]\n";
+                       throw new AAIException("AAI_6132", emsg); 
+               }
+               else { 
+                       while( modVertsIter.hasNext() ){
+                               Vertex tmpModelVerVtx = (Vertex) modVertsIter.next();
+                               retVtxArr.add(tmpModelVerVtx);
+                       }
+               }
+               
+               return retVtxArr;
+               
+       }// End getModelVersUsingName()
+       
+       
+       /**
+        * Gets the model-ver nodes using model-invariant-id.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param model-invariant-id (uniquely identifies a model)
+        * @return the model-ver's defined for the corresponding model 
+        * @throws AAIException the AAI exception
+        */
+       public Iterator<Vertex> getModVersUsingModelInvId( String transId, String fromAppId,
+                       String modelInvId )
+               throws AAIException {
+               
+               // Given a "model-invariant-id", find the model-ver nodes that this maps to
+               if( modelInvId == null || modelInvId.equals("")  ){
+                       String emsg = " Bad model-invariant-id passed to getModVersUsingModelInvId(): [" 
+                                       + modelInvId + "]\n";
+                       throw new AAIException("AAI_6118", emsg); 
+               }
+               
+               Vertex modVtx = getNodeUsingUniqueId(transId, fromAppId, "model", "model-invariant-id", modelInvId);
+               List<Vertex> retVtxArr =  getModVersUsingModel(transId, fromAppId, modVtx);
+               if( retVtxArr == null || retVtxArr.isEmpty() ){
+                       String emsg = " Model-ver record(s) could not be found attached to model with model-invariant-id = [" + 
+                                       modelInvId + "]\n";
+                       throw new AAIException("AAI_6132", emsg); 
+               }
+               
+               return retVtxArr.iterator();
+       }// End getModVersUsingModelInvId()
+       
+       
+       /**
+        * Gets the model-ver nodes using a model node.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param  model vertex
+        * @return the model-ver's defined for the corresponding model 
+        * @throws AAIException the AAI exception
+        */
+       public List<Vertex> getModVersUsingModel( String transId, String fromAppId,
+                       Vertex modVtx )
+               throws AAIException {
+               
+               if( modVtx == null ){
+                       String emsg = " Null model vertex passed to getModVersUsingModel(): ";
+                       throw new AAIException("AAI_6118", emsg); 
+               }
+               
+               List<Vertex> retVtxArr = new ArrayList<>();
+               Iterator<Vertex> modVerVertsIter = this.traverseIncidentEdges(EdgeType.TREE, modVtx, "model-ver");
+               if(!modVerVertsIter.hasNext()){
+                       String modelInvId = modVtx.<String>property("model-invariant-id").orElse(null);
+                       String emsg = "Model-ver record(s) could not be found attached to model with model-invariant-id = [" + 
+                                       modelInvId + "]\n";
+                       throw new AAIException("AAI_6132", emsg); 
+               }
+               else { 
+                       while( modVerVertsIter.hasNext() ){
+                               Vertex tmpModelVtx = (Vertex) modVerVertsIter.next();
+                               retVtxArr.add(tmpModelVtx);
+                       }
+               }
+               
+               return retVtxArr;
+               
+       }// End getModVersUsingModel()
+       
+       /**
+        * Gets the model-version-ids using model-name.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param modelName the model name
+        * @return the model uuids using name
+        * @throws AAIException the AAI exception
+        */
+       public List<String> getModelVerIdsUsingName( String transId, String fromAppId,
+                       String modelName )
+               throws AAIException {
+               
+               // Given a model-name find the model-ver nodes that it maps to
+               if( modelName == null || modelName.equals("")  ){
+                       String emsg = " Bad modelName passed to getModelVerIdsUsingName(): [" 
+                                       + modelName + "]\n";
+                       throw new AAIException("AAI_6118", emsg); 
+               }
+               
+               List<String> retArr = new ArrayList<>();
+               Iterator<Vertex> modVerVertsIter = this.engine.asAdmin().getReadOnlyTraversalSource().V().has(AAIProperties.NODE_TYPE,"model-ver").has("model-name",modelName);
+               if( !modVerVertsIter.hasNext() ){
+                       String emsg = " model-ver record(s) could not be found for model data passed.  model-name = [" + 
+                                       modelName + "]\n";
+                       throw new AAIException("AAI_6114", emsg); 
+               }
+               else { 
+                       while( modVerVertsIter.hasNext() ){
+                               Vertex modelVerVtx = (Vertex) modVerVertsIter.next();
+                               String tmpUuid = modelVerVtx.<String>property("model-version-id").orElse(null);
+                               if( (tmpUuid != null) && !tmpUuid.equals("") && !retArr.contains(tmpUuid) ){
+                                       retArr.add(tmpUuid);
+                               }
+                       }
+               }
+               
+               if( retArr.isEmpty() ){
+                       String emsg = "No model-ver record found for model-name = [" 
+                                       + modelName + "]\n";
+                       throw new AAIException("AAI_6132", emsg); 
+               }
+               
+               return retArr;
+       }// End getModelVerIdsUsingName()
+       
+       
+       /**
+        * Gets the model top widget type.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param modelVersionId the model-version-id
+        * @param modelInvId the model-invariant-id
+        * @param modelName the model-name
+        * @return the model top widget type
+        * @throws AAIException the AAI exception
+        */
+       public String getModelVerTopWidgetType( String transId, String fromAppId,
+                       String modelVersionId, String modelInvId, String modelName )
+               throws AAIException {
+               
+               // Could be given a model-ver's key info (model-version-id), OR, just a (non-unique) model-name,
+               //     Or just a model-invariant-id (which could have multiple model-ver records under it).
+               //     In any case, they should only map to one single "top" node-type for the first element. 
+               
+               String nodeType = "?";
+               Iterator<Vertex> modVerVertsIter;
+               
+               if( modelVersionId != null && !modelVersionId.equals("") ){
+                       // this would be the best - we can just look up the model-ver records directly
+                       modVerVertsIter = this.engine.asAdmin().getReadOnlyTraversalSource().V().has(AAIProperties.NODE_TYPE,"model-ver").has("model-version-id",modelVersionId);
+               }
+               else if( modelName != null && !modelName.equals("") ){
+                       modVerVertsIter = this.engine.asAdmin().getReadOnlyTraversalSource().V().has(AAIProperties.NODE_TYPE,"model-ver").has("model-name",modelName);
+               }
+               else if( modelInvId != null && !modelInvId.equals("") ){
+                       modVerVertsIter = getModVersUsingModelInvId(transId, fromAppId, modelInvId);
+               }
+               else {
+                       String msg = "Neither modelVersionId, modelInvariantId, nor modelName passed to: getModelVerTopWidgetType() ";
+                       throw new AAIException("AAI_6120", msg);
+               }
+               
+               if( !modVerVertsIter.hasNext() ){
+                       String emsg = "model-ver record(s) could not be found for model data passed:  modelInvariantId = [" + modelInvId +
+                                       "], modeVersionId = [" + modelVersionId + "], modelName = [" + modelName + "]\n";
+                       throw new AAIException("AAI_6114", emsg); 
+               }
+               else { 
+                       String lastNT = "";
+                       if( !modVerVertsIter.hasNext() ){
+                               String emsg = "model-ver record(s) could not be found for model data passed:  modelInvariantId = [" + modelInvId +
+                                               "], modeVersionId = [" + modelVersionId + "], modelName = [" + modelName + "]\n";
+                               throw new AAIException("AAI_6114", emsg); 
+                       }
+                       while( modVerVertsIter.hasNext() ){
+                               Vertex tmpModVerVtx = (Vertex) modVerVertsIter.next();
+                               String tmpNT = getModelVerTopWidgetType( tmpModVerVtx, "" );
+                               if( lastNT != null && !lastNT.equals("") ){
+                                       if( !lastNT.equals(tmpNT) ){
+                                               String emsg = "Different top-node-types (" + tmpNT + ", " + lastNT 
+                                                               + ") found for model data passed.  (" +
+                                                               " modelVersionId = [" + modelVersionId + 
+                                                               "], modelId = [" + modelInvId +
+                                                               "], modelName = [" + modelName +
+                                                               "])\n";
+                                               throw new AAIException("AAI_6114", emsg); 
+                                       }
+                               }
+                               lastNT = tmpNT;
+                               nodeType = tmpNT;
+                       }
+               }
+               
+               return nodeType;
+               
+       }// End getModelVerTopWidgetType()
+       
+                       
+       /**
+        * Gets the widget type that this model-ver starts with.
+        *
+        * @param modVerVtx the model-version vtx
+        * @param elementTrail the element trail
+        * @return the widget type of the starting node of this model
+        * @throws AAIException the AAI exception
+        */
+       public String getModelVerTopWidgetType( Vertex modVerVtx, String elementTrail )
+                               throws AAIException {
+               // Get the associated nodeType (Ie. aai-node-type / widget-type) for a model-ver.
+               // NOTE -- if the element points to a resource or service model, then we'll return the
+               //        widget-type of the first element (crown widget) for that model.
+               String modelType = getModelTypeFromModelVer( modVerVtx, elementTrail );
+               if( modelType == null ){
+                       String msg = " Could not determine modelType in getModelVerTopWidgetType().  elementTrail = [" + elementTrail + "].";
+                       throw new AAIException("AAI_6132", msg);
+               }
+                 
+               String thisElementNodeType = "?";
+               if( modelType.equals("widget") ){
+                       // NOTE: for models that have model-type = "widget", their child model-ver nodes will
+                       //       have "model-name" which maps directly to aai-node-type (all model-ver's under one
+                       //       model should start with the same widget-type, so we only need to look at one).
+                       thisElementNodeType = modVerVtx.<String>property("model-name").orElse(null);
+                       if( (thisElementNodeType == null) || thisElementNodeType.equals("") ){
+                               String msg = "Could not find model-name for the widget model pointed to by element at [" + elementTrail + "].";
+                               throw new AAIException("AAI_6132", msg);
+                       }
+               }
+               else if( modelType.equals("resource") || modelType.equals("service") ){
+                       Vertex relatedTopElementVtx = getTopElementForSvcOrResModelVer( modVerVtx, elementTrail );
+                       Vertex relatedModVerVtx = getModelVerThatElementRepresents( relatedTopElementVtx, elementTrail );
+                       thisElementNodeType = relatedModVerVtx.<String>property("model-name").orElse(null);
+                       if( (thisElementNodeType == null) || thisElementNodeType.equals("") ){
+                               String msg = "Could not find model-name for the widget model pointed to by element at [" + elementTrail + "].";
+                               throw new AAIException("AAI_6132", msg);
+                       }
+               }
+               else {
+                       String msg = " Unrecognized model-type = [" + modelType + "] pointed to by element at [" + elementTrail + "].";
+                       throw new AAIException("AAI_6132", msg);
+               }
+                
+               return thisElementNodeType;
+               
+       }// getModelVerTopWidgetType()
+       
+       
+       /**
+        * Validate model.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param modelNameVersionId the model name version id
+        * @param apiVersion the api version
+        * @throws AAIException the AAI exception
+        */
+       public void validateModel(String transId, String fromAppId, String modelVersionIdVal, String apiVersion ) 
+                               throws AAIException{
+       
+               // Note - this will throw an exception if the model either can't be found, or if 
+               //     we can't figure out its topology map.
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               Vertex modelVerVtx = getNodeUsingUniqueId(transId, fromAppId, "model-ver", 
+                               "model-version-id", modelVersionIdVal);
+               if( modelVerVtx == null ){
+                       String msg = " Could not find model-ver with modelVersionId = [" + modelVersionIdVal + "].";
+                       throw new AAIException("AAI_6114", msg);
+               }
+               else {
+                       Multimap<String, String> topoMap = genTopoMap4ModelVer( transId, fromAppId,
+                                       modelVerVtx, modelVersionIdVal, dbMaps );
+                       String msg = " modelVer [" + modelVersionIdVal + "] topo multiMap looks like: \n[" + topoMap + "]";
+                       System.out.println("INFO --  " + msg );
+               }
+               return;
+               
+       }// End validateModel()
+       
+       
+       /**
+        * Validate named query.
+        *
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param namedQueryUuid the named query uuid
+        * @param apiVersion the api version
+        * @throws AAIException the AAI exception
+        */
+       public void validateNamedQuery(String transId, String fromAppId, String namedQueryUuid, String apiVersion ) 
+                               throws AAIException{
+       
+               // Note - this will throw an exception if the named query either can't be found, or if 
+               //     we can't figure out its topology map.
+               Vertex nqVtx = getNodeUsingUniqueId(transId, fromAppId, "named-query", 
+                               "named-query-uuid", namedQueryUuid);
+               
+               if( nqVtx == null ){
+                       String msg = " Could not find named-query with namedQueryUuid = [" + namedQueryUuid + "].";
+                       throw new AAIException("AAI_6114", msg);
+               }
+               else {
+                       //Multimap<String, String> topoMap = genTopoMap4NamedQ( "junkTransId", "junkFromAppId", 
+                               //      graph, nqVtx, namedQueryUuid );
+                       //System.out.println("DEBUG -- for test only : --- ");
+                       //System.out.println("DEBUG -- topomap = [" + topoMap + "]");
+               }
+               return;
+               
+       }// End validateNamedQuery()
+       
+         
+       /**
+        * Show result set.
+        *
+        * @param resSet the res set
+        * @param levelCount the level count
+        */
+       public void showResultSet( ResultSet resSet, int levelCount ) {
+               
+                 levelCount++;
+                 String propsStr = "";
+                 for( int i= 1; i <= levelCount; i++ ){
+                         propsStr = propsStr + "-";
+                 }
+                 if( resSet.getVert() == null ){
+                         return;
+                 }
+                 String nt = resSet.getVert().<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                 propsStr = propsStr +  "[" + nt + "] ";
+                
+                 //propsStr = propsStr + " newDataDelFlag = " + resSet.getNewDataDelFlag() + ", trail = " + resSet.getLocationInModelSubGraph();
+                 //propsStr = propsStr + "limitDesc = [" + resSet.getPropertyLimitDesc() + "]";
+                 propsStr = propsStr + " trail = " + resSet.getLocationInModelSubGraph();
+                 
+                 Map<String,Object> overrideHash = resSet.getPropertyOverRideHash();
+                 if( overrideHash != null  &&  !overrideHash.isEmpty() ){
+                         for( Map.Entry<String, Object> entry : overrideHash.entrySet() ){
+                                 String propName = entry.getKey();
+                                 Object propVal = entry.getValue();
+                                 propsStr = propsStr + " [" + propName + " = " + propVal + "]";
+                         }
+                 }
+                 else {
+                         Iterator<VertexProperty<Object>> pI = resSet.getVert().properties();
+                         while( pI.hasNext() ){
+                                       VertexProperty<Object> tp = pI.next();
+                                       if( ! tp.key().startsWith("aai") 
+                                                       && ! tp.key().equals("source-of-truth")
+                                                       //&& ! tp.key().equals("resource-version")
+                                                       && ! tp.key().startsWith("last-mod")
+                                                       )
+                                       {
+                                               propsStr = propsStr + " [" + tp.key() + " = " + tp.value() + "]";
+                                       }
+                         }
+                 }
+                 // Show the "extra" lookup values too
+                 Map<String,Object> extraPropHash = resSet.getExtraPropertyHash();
+                 if( extraPropHash != null && !extraPropHash.isEmpty() ){
+                         for( Map.Entry<String, Object> entry : extraPropHash.entrySet() ){
+                                 String propName = entry.getKey();
+                                 Object propVal = entry.getValue();
+                                 propsStr = propsStr + " [" + propName + " = " + propVal.toString() + "]";
+                         }
+                 }
+                 
+                 System.out.println( propsStr );
+                 LOGGER.info(propsStr);
+                 
+                 if( !resSet.getSubResultSet().isEmpty() ){
+                         ListIterator<ResultSet> listItr = resSet.getSubResultSet().listIterator();
+                         while( listItr.hasNext() ){
+                                 showResultSet( listItr.next(), levelCount );
+                         }
+                 }
+                 
+         }// end of showResultSet()
+       
+       private Iterator<Vertex> traverseIncidentEdges(EdgeType treeType, Vertex startV, String connectedNodeType) throws AAIUnknownObjectException, AAIException {
+               QueryBuilder builder = this.engine.getQueryBuilder(startV).createEdgeTraversal(treeType, startV, loader.introspectorFromName(connectedNodeType));
+               return builder;
+       }
+       
+       private Iterator<Vertex> traverseIncidentEdges(EdgeType treeType, Vertex startV, String... connectedNodeType) throws AAIUnknownObjectException, AAIException {
+               QueryBuilder[] builders = new QueryBuilder[connectedNodeType.length];
+               for (int i = 0; i < connectedNodeType.length; i++) {
+                       builders[i] = this.engine.getQueryBuilder(startV).createEdgeTraversal(EdgeType.TREE, startV, loader.introspectorFromName(connectedNodeType[i]));
+               }
+               QueryBuilder builder = this.engine.getQueryBuilder(startV).union(builders);
+               return builder;
+
+       }
+                 
+}
+
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/ResultSet.java b/aai-traversal/src/main/java/org/openecomp/aai/dbgraphgen/ResultSet.java
new file mode 100644 (file)
index 0000000..46c9b5e
--- /dev/null
@@ -0,0 +1,168 @@
+/*-
+ * ============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.dbgraphgen;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.openecomp.aai.dbgen.PropertyLimitDesc;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+public class ResultSet {
+       private TitanVertex vert;
+       private String newDataDelFlag;  
+       private String doNotOutputFlag;
+       private String locationInModelSubGraph;
+       private List<ResultSet> subResultSet;
+       private PropertyLimitDesc propertyLimitDesc;
+       private Map<String,Object> propertyOverRideHash;
+       private Map<String,Object> extraPropertyHash;
+       
+        /**
+        * Instantiates a new result set.
+        */
+       public ResultSet(){
+                this.vert = null;
+                this.newDataDelFlag = "";
+                this.doNotOutputFlag = "";
+                this.locationInModelSubGraph = "";
+                this.subResultSet = new ArrayList<>();
+                this.propertyLimitDesc = null;
+                this.propertyOverRideHash = new HashMap<>();
+                this.extraPropertyHash = new HashMap<>();
+       }
+        
+       
+       public void setPropertyLimitDesc(PropertyLimitDesc pld) {
+               this.propertyLimitDesc = pld;
+       }
+
+       /**
+        * Gets the vert.
+        *
+        * @return the vert
+        */
+       public TitanVertex getVert(){
+                return this.vert;
+        }
+        
+       /**
+        * Gets the sub result set.
+        *
+        * @return the sub result set
+        */
+       public List<ResultSet> getSubResultSet(){
+                return this.subResultSet;
+        }
+        
+       /**
+        * Gets the new data del flag.
+        *
+        * @return the new data del flag
+        */
+       public String getNewDataDelFlag(){
+                return this.newDataDelFlag;
+        }
+        
+       /**
+        * Gets the do not output flag.
+        *
+        * @return the do not output flag
+        */
+       public String getDoNotOutputFlag(){
+                return this.doNotOutputFlag;
+        }
+        
+       /**
+        * Gets the location in model sub graph.
+        *
+        * @return the location in model sub graph
+        */
+       public String getLocationInModelSubGraph(){
+                return this.locationInModelSubGraph;
+        }
+        
+       /**
+        * Gets the property limit desc.
+        *
+        * @return the property limit desc
+        */
+       public PropertyLimitDesc getPropertyLimitDesc(){
+                return this.propertyLimitDesc;
+        }
+        
+       /**
+        * Gets the property over ride hash.
+        *
+        * @return the property over ride hash
+        */
+       public Map<String,Object> getPropertyOverRideHash(){
+                return this.propertyOverRideHash;
+        }
+        
+       /**
+        * Gets the extra property hash.
+        *
+        * @return the extra property hash
+        */
+       public Map<String,Object> getExtraPropertyHash(){
+                return this.extraPropertyHash;
+        }
+
+
+       public void setVert(TitanVertex vert) {
+               this.vert = vert;
+       }
+
+
+       public void setNewDataDelFlag(String newDataDelFlag) {
+               this.newDataDelFlag = newDataDelFlag;
+       }
+
+
+       public void setDoNotOutputFlag(String doNotOutputFlag) {
+               this.doNotOutputFlag = doNotOutputFlag;
+       }
+
+
+       public void setLocationInModelSubGraph(String locationInModelSubGraph) {
+               this.locationInModelSubGraph = locationInModelSubGraph;
+       }
+
+
+       public void setSubResultSet(List<ResultSet> subResultSet) {
+               this.subResultSet = subResultSet;
+       }
+
+
+       public void setPropertyOverRideHash(Map<String, Object> propertyOverRideHash) {
+               this.propertyOverRideHash = propertyOverRideHash;
+       }
+
+
+       public void setExtraPropertyHash(Map<String, Object> extraPropertyHash) {
+               this.extraPropertyHash = extraPropertyHash;
+       }
+       
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/dbgraphmap/RelationshipGraph.java b/aai-traversal/src/main/java/org/openecomp/aai/dbgraphmap/RelationshipGraph.java
new file mode 100644 (file)
index 0000000..8277b2c
--- /dev/null
@@ -0,0 +1,299 @@
+/*-
+ * ============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.dbgraphmap;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.map.MultiValueMap;
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.dynamic.DynamicType;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+
+import org.openecomp.aai.dbgen.DbMeth;
+import org.openecomp.aai.dbgraphgen.DbEdgeGroup;
+import org.openecomp.aai.domain.model.AAIResources;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.extensions.AAIExtensionMap;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import org.openecomp.aai.util.RestURL;
+import com.thinkaurelius.titan.core.TitanTransaction;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+public class RelationshipGraph {
+       
+       /**
+        * this method processes the one relationship for the startVertex that is
+        * sent.
+        *
+        * @param g the g
+        * @param startVertex the start vertex
+        * @param jaxbContext the jaxb context
+        * @param rel the rel
+        * @param aaiExtMap the aai ext map
+        * @throws AAIException the AAI exception
+        */
+       public static void updRelationship(TitanTransaction g, TitanVertex startVertex, 
+                                                                               DynamicJAXBContext jaxbContext,
+                                                                               DynamicEntity rel,
+                                                                               AAIExtensionMap aaiExtMap)
+               throws AAIException {
+               String apiVersion = aaiExtMap.getApiVersion();
+               String transId = aaiExtMap.getTransId();
+               String fromAppId = aaiExtMap.getFromAppId();
+               MultiValueMap relatedNodesMap = new MultiValueMap();
+               
+               if( rel != null ){
+                               HashMap<String, Object> propFilterHash = new HashMap<String, Object>();
+                               poplatePropertyHashWithRelData(rel, apiVersion, propFilterHash);
+                               String relNodeType = (String)rel.get("relatedTo");
+                               relatedNodesMap.put(relNodeType, propFilterHash);
+               }
+               DbEdgeGroup.replaceEdgeGroup(transId, fromAppId, g, startVertex,
+                                               "ONLY_PASSED_COUSINS_REL", relatedNodesMap, apiVersion);
+
+       }
+
+       /**
+        * Poplate property hash with rel data.
+        *
+        * @param rel the rel
+        * @param apiVersion the api version
+        * @param propFilterHash the prop filter hash
+        * @throws AAIException the AAI exception
+        */
+       private static void poplatePropertyHashWithRelData(DynamicEntity rel, String apiVersion,
+                       HashMap<String, Object> propFilterHash) throws AAIException {
+               
+               for( DynamicEntity relData: (List<DynamicEntity>)rel.get("relationshipData")) {
+                       String prop = ((String)relData.get("relationshipKey")).toLowerCase().trim();
+                       propFilterHash.put(prop, ((String)relData.get("relationshipValue")).trim()); 
+               } 
+       }
+
+       /**
+        * this method gets any relationships for the startVertex being processed
+        * and sets the related-link.
+        *
+        * @param g the g
+        * @param startVertex the start vertex
+        * @param apiVersion the api version
+        * @param aaiExtMap the aai ext map
+        * @return the relationships
+        * @throws AAIException the AAI exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public static DynamicEntity getRelationships(TitanTransaction g, TitanVertex startVertex, 
+                                                                                               String apiVersion, AAIExtensionMap aaiExtMap)
+                       throws AAIException, UnsupportedEncodingException {
+               
+               DynamicType relationshipsType = null;
+               DynamicType relationshipType = null;
+               DynamicType relationshipDataType = null;
+               DynamicType relatedToPropertyType = null;
+               
+               Boolean setRelatedToProperty = true;
+               
+               AAIResources aaiResources = org.openecomp.aai.ingestModel.IngestModelMoxyOxm.aaiResourceContainer
+                               .get(apiVersion);
+
+               DynamicJAXBContext jaxbContext = aaiResources.getJaxbContext();
+                               
+               //String apiVersion = aaiExtMap.getApiVersion();
+               String transId = aaiExtMap.getTransId();
+               String fromAppId = aaiExtMap.getFromAppId();
+               
+               HashMap <String, String>      vidToNodeTypeHash = new HashMap <String, String>();
+               HashMap <String, TitanVertex> vidToVertexHash   = new HashMap <String, TitanVertex>();
+               
+               if ("v2".equals( apiVersion)) { 
+                       relationshipsType = jaxbContext.getDynamicType("inventory.aai.openecomp.org.RelationshipList");
+                       relationshipType = jaxbContext.getDynamicType(".org.Relationship");
+                       relationshipDataType = jaxbContext.getDynamicType("inventory.aai.openecomp.org.RelationshipData");
+                       setRelatedToProperty = false;
+               } else { 
+                       relationshipsType = jaxbContext.getDynamicType("inventory.aai.openecomp.org." + apiVersion + ".RelationshipList");
+                       relationshipType = jaxbContext.getDynamicType("inventory.aai.openecomp.org." + apiVersion + ".Relationship");
+                       relationshipDataType = jaxbContext.getDynamicType("inventory.aai.openecomp.org." + apiVersion + ".RelationshipData");
+                       relatedToPropertyType = jaxbContext.getDynamicType("inventory.aai.openecomp.org." + apiVersion + ".RelatedToProperty");
+                       if (relatedToPropertyType == null) { 
+                               setRelatedToProperty = false; // some versions do not support this
+                       }
+               }
+               
+               DynamicEntity relationships = relationshipsType.newDynamicEntity();
+               List<DynamicEntity> listOfRelationships = new ArrayList<DynamicEntity>();
+                       
+               DbEdgeGroup.getEdgeGroup(transId,
+                               fromAppId, 
+                               g, 
+                               startVertex, 
+                               vidToNodeTypeHash,
+                               vidToVertexHash,
+                               "ONLY_COUSIN_REL", 
+                               AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               // Convert the found relationships to a RelationshipList DynamicEntity
+               for( Map.Entry<String, TitanVertex> entry : vidToVertexHash.entrySet() ){
+                       
+                       List<DynamicEntity> relationshipDataList = new ArrayList<DynamicEntity>();
+                       List<DynamicEntity> relatedToPropertyList = new ArrayList<DynamicEntity>();
+                       
+                       DynamicEntity relationship = relationshipType.newDynamicEntity();
+                       
+                       TitanVertex relNode = entry.getValue();
+                       String relNodeVid = entry.getKey();
+                       String relNodeType = vidToNodeTypeHash.get(relNodeVid);
+                       String relNodeURL = RestURL.get(g, relNode, apiVersion);
+                       
+                       HashMap <String, Object> nodeKeyPropsHash = RestURL.getKeyHashes(g, relNode, AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+                       Iterator  <Map.Entry<String,Object>>keyIterator = nodeKeyPropsHash.entrySet().iterator();
+                       while( keyIterator.hasNext() ){
+                               DynamicEntity relationshipData = relationshipDataType.newDynamicEntity();
+                               Map.Entry <String,Object>pair = (Map.Entry<String,Object>)keyIterator.next();
+                               String key = pair.getKey();
+                               
+                               if (!key.contains(".")) {
+                                       key = relNodeType + "." + key;
+                               }
+                               
+                               String value = "";
+                               if( pair.getValue() != null ){
+                                       value = pair.getValue().toString();
+                               }
+                               
+                               relationshipData.set("relationshipKey", key);
+                               relationshipData.set("relationshipValue", value);
+       
+                               relationshipDataList.add(relationshipData);
+                       }
+                       
+                       if (setRelatedToProperty) {
+                               HashMap <String, Object> nodeNamePropsHash = DbMeth.getNodeNamePropHash(transId, fromAppId, g, relNode, AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+                               Iterator  <Map.Entry<String,Object>>nameIterator = nodeNamePropsHash.entrySet().iterator();
+                               while( nameIterator.hasNext() ){
+                                       DynamicEntity relatedToProperty = relatedToPropertyType.newDynamicEntity();
+                                       Map.Entry <String,Object>pair = (Map.Entry<String,Object>)nameIterator.next();
+                                       String key = pair.getKey();
+                                       
+                                       if (!key.contains(".")) {
+                                               key = relNodeType + "." + key;
+                                       }
+                                       
+                                       String value = "";
+                                       if( pair.getValue() != null ){
+                                               value = pair.getValue().toString();
+                                       }
+                                       relatedToProperty.set("propertyKey", key);
+                                       relatedToProperty.set("propertyValue", value);
+       
+                                       relatedToPropertyList.add(relatedToProperty);
+       
+                               }
+                               relationship.set("relatedToProperty", relatedToPropertyList);
+                       }
+                       relationship.set("relatedTo", relNodeType);
+                       relationship.set("relatedLink", relNodeURL);
+                       relationship.set("relationshipData", relationshipDataList);
+
+                       listOfRelationships.add(relationship);
+               }
+               relationships.set("relationship",  listOfRelationships);
+               return relationships;
+       }
+
+       /**
+        * this method processes any relationships for the startVertex being
+        * processed.
+        *
+        * @param g the g
+        * @param startVertex the start vertex
+        * @param jaxbContext the jaxb context
+        * @param relationshipList the relationship list
+        * @param aaiExtMap the aai ext map
+        * @throws AAIException the AAI exception
+        */
+       public static void updRelationships(TitanTransaction g, TitanVertex startVertex, 
+                                                                               DynamicJAXBContext jaxbContext,
+                                                                               DynamicEntity relationshipList,
+                                                                               AAIExtensionMap aaiExtMap) 
+       throws AAIException {
+                
+                       String apiVersion = aaiExtMap.getApiVersion();
+                       String transId = aaiExtMap.getTransId();
+                       String fromAppId = aaiExtMap.getFromAppId();
+                       MultiValueMap relatedNodesMap = new MultiValueMap();
+                       if (relationshipList != null) { 
+                               if( relationshipList.get("relationship") != null ){
+                                       List <DynamicEntity> relListTmp = relationshipList.get("relationship");
+                                       for( DynamicEntity rel: relListTmp) {
+                                               HashMap<String, Object> propFilterHash = new HashMap<String, Object>();
+                                               poplatePropertyHashWithRelData(rel, apiVersion, propFilterHash);
+                                               String relNodeType = (String)rel.get("relatedTo");
+                                               relatedNodesMap.put(relNodeType, propFilterHash);
+                                               
+
+                                       }
+                               }
+                               DbEdgeGroup.replaceEdgeGroup(transId, fromAppId, g, startVertex,
+                                               "ALL_COUSIN_REL", relatedNodesMap, apiVersion);
+                       }
+       }
+
+       /**
+        * this method deletes the relationship sent in for the startVertex being
+        * processed.
+        *
+        * @param g the g
+        * @param startVertex the start vertex
+        * @param jaxbContext the jaxb context
+        * @param rel the rel
+        * @param aaiExtMap the aai ext map
+        * @throws AAIException the AAI exception
+        */
+       public static void delRelationship(TitanTransaction g, TitanVertex startVertex, 
+                               DynamicJAXBContext jaxbContext,
+                               DynamicEntity rel,
+                               AAIExtensionMap aaiExtMap) 
+       throws AAIException {
+
+               String apiVersion = aaiExtMap.getApiVersion();
+               String transId = aaiExtMap.getTransId();
+               String fromAppId = aaiExtMap.getFromAppId();
+               MultiValueMap relatedNodesMap = new MultiValueMap();
+               
+               if( rel != null ){
+                       HashMap<String, Object> propFilterHash = new HashMap<String, Object>();
+                       poplatePropertyHashWithRelData(rel, apiVersion, propFilterHash);
+                       String relNodeType = (String)rel.get("relatedTo");
+                       relatedNodesMap.put(relNodeType, propFilterHash);
+       }
+
+               DbEdgeGroup.deleteEdgeGroup(transId, fromAppId, g, startVertex,
+                               relatedNodesMap, apiVersion);
+
+       }
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/dbgraphmap/SearchGraph.java b/aai-traversal/src/main/java/org/openecomp/aai/dbgraphmap/SearchGraph.java
new file mode 100644 (file)
index 0000000..f45c3f5
--- /dev/null
@@ -0,0 +1,1207 @@
+/*-
+ * ============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.dbgraphmap;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilderException;
+import javax.xml.bind.JAXBException;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+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.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.dynamic.DynamicType;
+import org.eclipse.persistence.exceptions.DynamicException;
+import org.eclipse.persistence.jaxb.JAXBMarshaller;
+import org.eclipse.persistence.jaxb.JAXBUnmarshaller;
+import org.eclipse.persistence.jaxb.MarshallerProperties;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+
+import org.openecomp.aai.db.DbMethHelper;
+import org.openecomp.aai.db.props.AAIProperties;
+import org.openecomp.aai.dbgen.PropertyLimitDesc;
+import org.openecomp.aai.dbgraphgen.ModelBasedProcessing;
+import org.openecomp.aai.dbgraphgen.ResultSet;
+import org.openecomp.aai.dbmap.DBConnectionType;
+import org.openecomp.aai.domain.model.AAIResources;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.extensions.AAIExtensionMap;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.LoaderFactory;
+import org.openecomp.aai.introspection.ModelType;
+import org.openecomp.aai.introspection.PropertyPredicates;
+import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.openecomp.aai.parsers.relationship.RelationshipToURI;
+import org.openecomp.aai.query.builder.QueryBuilder;
+import org.openecomp.aai.schema.enums.ObjectMetadata;
+import org.openecomp.aai.schema.enums.PropertyMetadata;
+import org.openecomp.aai.serialization.db.DBSerializer;
+import org.openecomp.aai.serialization.db.EdgeRule;
+import org.openecomp.aai.serialization.db.EdgeRules;
+import org.openecomp.aai.serialization.engines.QueryStyle;
+import org.openecomp.aai.serialization.engines.TitanDBEngine;
+import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
+import org.openecomp.aai.serialization.queryformats.utils.UrlBuilder;
+import org.openecomp.aai.util.AAIApiServerURLBase;
+import org.openecomp.aai.util.AAIApiVersion;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import org.openecomp.aai.util.PojoUtils;
+import org.openecomp.aai.util.RestURL;
+import org.openecomp.aai.util.StoreNotificationEvent;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.google.common.base.CaseFormat;
+import com.thinkaurelius.titan.core.TitanTransaction;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+import edu.emory.mathcs.backport.java.util.Collections;
+
+/**
+ * Database Mapping class which acts as the middle man between the REST interface objects 
+ * for the Search namespace 
+
+ */
+public class SearchGraph {
+
+       private final String COMPONENT = "aaidbmap";
+       private AAIExtensionMap aaiExtMap;
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(SearchGraph.class);
+       /**
+        * Get the search result based on the includeNodeType and depth provided.
+        *
+        * @param fromAppId the from app id
+        * @param transId the trans id
+        * @param startNodeType the start node type
+        * @param startNodeKeyParams the start node key params
+        * @param includeNodeTypes the include node types
+        * @param depth the depth
+        * @param aaiExtMap the aai ext map
+        * @return Response
+        * @throws AAIException the AAI exception
+        */
+       public Response runGenericQuery (
+                       HttpHeaders headers,
+                       String startNodeType,
+                       List <String> startNodeKeyParams,
+                       List <String> includeNodeTypes,
+                       final int depth,
+                       TransactionalGraphEngine dbEngine,
+                       Loader loader,
+                       UrlBuilder urlBuilder) throws AAIException {
+               Response response = null;
+               boolean success = true;
+               String result = "";
+               try {                   
+                       dbEngine.startTransaction();
+
+                       if( startNodeType == null ){
+                               throw new AAIException("AAI_6120", "null start-node-type passed to the generic query"); 
+                       }
+
+                       if( startNodeKeyParams == null ){
+                               throw new AAIException("AAI_6120", "no key param passed to the generic query"); 
+                       }
+
+                       if( includeNodeTypes == null ){
+                               throw new AAIException("AAI_6120", "no include params passed to the generic query"); 
+                       }
+
+                       if (depth > 6) {
+                               throw new AAIException("AAI_6120", "The maximum depth supported by the generic query is 6");
+                       }
+                       final QueryBuilder queryBuilder;
+                       
+                       // there is an issue with service-instance - it is a unique node but still dependent
+                       // for now query it directly without attempting to craft a valid URI    
+                       if (startNodeType.equalsIgnoreCase("service-instance")) {
+                               Introspector obj = loader.introspectorFromName(startNodeType);
+                               // Build a hash with keys to uniquely identify the start Node
+                               String keyName = null;
+                               String keyValue = null;
+
+                               QueryBuilder builder = dbEngine.getQueryBuilder().getVerticesByIndexedProperty(AAIProperties.NODE_TYPE, "service-instance");
+                               for( String keyData : startNodeKeyParams ){ 
+                                       int colonIndex = keyData.indexOf(":");
+                                       if( colonIndex <= 0 ){
+                                               throw new AAIException("AAI_6120", "Bad key param passed in: [" + keyData + "]"); 
+                                       }
+                                       else {
+                                               keyName = keyData.substring(0, colonIndex).split("\\.")[1];
+                                               keyValue = keyData.substring(colonIndex + 1);
+                                               builder.getVerticesByProperty(keyName, keyValue);
+                                               
+                                       }
+                               }
+                               
+                               queryBuilder = builder;
+                       } else {
+                               URI uri = craftUriFromQueryParams(loader, startNodeType, startNodeKeyParams);
+                               queryBuilder = dbEngine.getQueryBuilder().createQueryFromURI(uri).getQueryBuilder();
+                       }
+                       List<Vertex> results = queryBuilder.toList();
+                       if( results.isEmpty()){
+                               throw new AAIException("AAI_6114", "No Node of type " + 
+                                               startNodeType + 
+                                               " found for properties: " + 
+                                               startNodeKeyParams.toString()); 
+                       } else if (results.size() > 1) {
+                               String detail = "More than one Node found by getUniqueNode for params: " + startNodeKeyParams.toString() + "\n";
+                               throw new AAIException("AAI_6112", detail); 
+                       }
+
+                       Vertex startNode = results.get(0);
+
+                       Collection <Vertex> ver = new HashSet <>();
+                       List<Vertex> queryResults = new ArrayList<>();
+                       GraphTraversalSource traversalSource = dbEngine.asAdmin().getReadOnlyTraversalSource();
+                       GraphTraversal<Vertex, Vertex> traversal;
+                       if (includeNodeTypes.contains(startNodeType) || depth == 0 || includeNodeTypes.contains("all") )
+                               ver.add(startNode);
+
+                       // Now look for a node of includeNodeType within a given depth
+                       traversal = traversalSource.withSideEffect("x", ver).V(startNode)
+                       .times(depth).repeat(__.both().store("x")).cap("x").unfold();
+                       
+                       if (!includeNodeTypes.contains("all")) {
+                               traversal.where(__.has(AAIProperties.NODE_TYPE, P.within(includeNodeTypes)));
+                       }
+                       queryResults = traversal.toList();
+                       
+
+                       if( queryResults.isEmpty()){
+                               LOGGER.warn("No nodes found - apipe was null/empty");
+                       }
+                       else {                                          
+                               
+                               Introspector searchResults = loader.introspectorFromName("search-results");
+                               List<Object> resultDataList = searchResults.getValue("result-data");
+                               for (Vertex thisNode: queryResults){
+                                       String nodeType = thisNode.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                                       
+                                       String thisNodeURL = urlBuilder.pathed(thisNode);
+                                       Introspector resultData = loader.introspectorFromName("result-data");
+                                       
+                                       resultData.setValue("resource-type", nodeType);
+                                       resultData.setValue("resource-link", thisNodeURL);
+                                       resultDataList.add(resultData.getUnderlyingObject());
+                                       
+                               }
+
+                               String outputMediaType = getMediaType(headers.getAcceptableMediaTypes());
+                               org.openecomp.aai.introspection.MarshallerProperties properties = new org.openecomp.aai.introspection.MarshallerProperties.Builder(
+                                               org.openecomp.aai.restcore.MediaType.getEnum(outputMediaType)).build();
+
+                               result = searchResults.marshal(properties);
+                               response = Response.ok().entity(result).build();
+
+                               LOGGER.debug(ver.size() + " node(s) traversed, " + resultDataList.size() + " found");
+                       }
+                       success = true;
+               } catch (AAIException e) { 
+                       success = false;
+                       throw e;
+               } catch (Exception e) {
+                       success = false;
+                       throw new AAIException("AAI_5105", e);
+               } finally {
+                       if (dbEngine != null) {
+                               if (success) {
+                                       dbEngine.commit();
+                               } else {
+                                       dbEngine.rollback();
+                               }
+                       }
+
+               }
+
+               return response;        
+       }       
+
+       private URI craftUriFromQueryParams(Loader loader, String startNodeType, List<String> startNodeKeyParams) throws UnsupportedEncodingException, IllegalArgumentException, UriBuilderException, AAIException {
+               Introspector relationship = loader.introspectorFromName("relationship");
+               
+               relationship.setValue("related-to", startNodeType);
+               List<Object> relationshipDataList = relationship.getValue("relationship-data");
+
+               for( String keyData : startNodeKeyParams ){ 
+                       int colonIndex = keyData.indexOf(":");
+                       if( colonIndex <= 0 ){
+                               throw new AAIException("AAI_6120", "Bad key param passed in: [" + keyData + "]"); 
+                       }
+                       else {
+                               Introspector data = loader.introspectorFromName("relationship-data");
+                               data.setValue("relationship-key", keyData.substring(0, colonIndex));
+                               data.setValue("relationship-value", keyData.substring(colonIndex + 1));
+                               relationshipDataList.add(data.getUnderlyingObject());
+                       }
+               }
+               
+               RelationshipToURI parser = new RelationshipToURI(loader, relationship);
+
+               return parser.getUri();
+       }
+
+       /**
+        * Run nodes query.
+        *
+        * @param fromAppId the from app id
+        * @param transId the trans id
+        * @param targetNodeType the target node type
+        * @param edgeFilterParams the edge filter params
+        * @param filterParams the filter params
+        * @param aaiExtMap the aai ext map
+        * @return Response
+        * @throws AAIException the AAI exception
+        */
+       public Response runNodesQuery (
+                       HttpHeaders headers,
+                       String targetNodeType,
+                       List <String> edgeFilterParams,
+                       List <String> filterParams,
+                       TransactionalGraphEngine dbEngine,
+                       Loader loader,
+                       UrlBuilder urlBuilder) throws AAIException {
+               
+               Response response = null;
+               boolean success = true;
+        String result = "";
+               final String EQUALS = "EQUALS";
+               final String DOES_NOT_EQUAL = "DOES-NOT-EQUAL";
+               final String EXISTS = "EXISTS";
+               final String DOES_NOT_EXIST = "DOES-NOT-EXIST";
+               try {
+                       
+                       dbEngine.startTransaction();
+                       
+                       Introspector target;
+                       
+                       if( targetNodeType == null || targetNodeType == "" ){
+                               throw new AAIException("AAI_6120", "null or empty target-node-type passed to the node query"); 
+                       }
+
+                       try {
+                               target = loader.introspectorFromName(targetNodeType);
+                       } catch (AAIUnknownObjectException e) {
+                               throw new AAIException("AAI_6115", "Unrecognized nodeType [" + targetNodeType + "] passed to node query."); 
+                       }
+                       
+                       if( filterParams.isEmpty()  && edgeFilterParams.isEmpty()){
+                               // For now, it's ok to pass no filter params.  We'll just return ALL the nodes of the requested type.
+                               LOGGER.warn("No filters passed to the node query");
+                       }
+
+                       StringBuilder queryStringForMsg = new StringBuilder();  
+                       GraphTraversal<Vertex, Vertex> traversal  = dbEngine.asAdmin().getReadOnlyTraversalSource().V().has(AAIProperties.NODE_TYPE, targetNodeType);
+                       queryStringForMsg.append("has(\"aai-node-type\"," + targetNodeType + ")");
+                       
+                       for( String filter : filterParams ) {
+                               String [] pieces = filter.split(":");
+                               if( pieces.length < 2 ){
+                                       throw new AAIException("AAI_6120", "bad filter passed to node query: [" + filter + "]"); 
+                               }
+                               else {
+                                       String propName = this.findDbPropName(target, pieces[0]);
+                                       String filterType = pieces[1];
+                                       if( filterType.equals(EQUALS)){
+                                               if( pieces.length < 3 ){ 
+                                                       throw new AAIException("AAI_6120", "No value passed for filter: [" + filter + "]"); 
+                                               }
+                                               String value = "?";
+                                               if( pieces.length == 3 ){
+                                                       value = pieces[2];
+                                               }
+                                               else if( pieces.length > 3 ){
+                                                       // When a ipv6 address comes in as a value, it has colons in it which require us to 
+                                                       // pull the "value" off the end of the filter differently
+                                                       int startPos4Value = propName.length() + filterType.length() + 3;
+                                                       value = filter.substring(startPos4Value);
+                                               }
+                                               queryStringForMsg.append(".has(" + propName + "," + value + ")");
+                                               traversal.has(propName,value);
+                                       }
+                                       else if( filterType.equals(DOES_NOT_EQUAL)){
+                                               if( pieces.length < 3 ){
+                                                       throw new AAIException("AAI_6120", "No value passed for filter: [" + filter + "]"); 
+                                               }
+                                               String value = "?";
+                                               if( pieces.length == 3 ){
+                                                       value = pieces[2];
+                                               }
+                                               else if( pieces.length > 3 ){
+                                                       // When a ipv6 address comes in as a value, it has colons in it which require us to 
+                                                       // pull the "value" off the end of the filter differently
+                                                       int startPos4Value = propName.length() + filterType.length() + 3;
+                                                       value = filter.substring(startPos4Value);
+                                               }
+                                               queryStringForMsg.append(".hasNot(" + propName + "," + value + ")");
+                                               traversal.not(__.has(propName,value));
+                                       }
+                                       else if( filterType.equals(EXISTS)){
+                                               queryStringForMsg.append(".has(" + propName + ")");
+                                               traversal.has(propName);
+                                       }
+                                       else if( filterType.equals(DOES_NOT_EXIST)){
+                                               queryStringForMsg.append(".hasNot(" + propName + ")");
+                                               traversal.hasNot(propName);
+                                       }
+                                       else {
+                                               throw new AAIException("AAI_6120", "bad filterType passed: [" + filterType + "]"); 
+                                       }
+                               }
+                       }
+
+                       if (!edgeFilterParams.isEmpty()) {
+                               // edge-filter=pserver:EXISTS: OR pserver:EXISTS:hostname:XXX
+                               // edge-filter=pserver:DOES-NOT-EXIST: OR pserver:DOES-NOT-EXIST:hostname:XXX
+                               String filter = edgeFilterParams.get(0); // we process and allow only one edge filter for now
+                               String [] pieces = filter.split(":");
+                               if( pieces.length < 2 || pieces.length == 3 || pieces.length > 4){
+                                       throw new AAIException("AAI_6120", "bad edge-filter passed: [" + filter + "]"); 
+                               } else {
+                                       String nodeType = pieces[0].toLowerCase();
+                                       String filterType = pieces[1].toUpperCase();
+                                       Introspector otherNode;
+                                       if (!filterType.equals(EXISTS) && !filterType.equals(DOES_NOT_EXIST)) {
+                                               throw new AAIException("AAI_6120", "bad filterType passed: [" + filterType + "]"); 
+                                       }
+                                       try {
+                                               otherNode = loader.introspectorFromName(nodeType);
+                                       } catch (AAIUnknownObjectException e) {
+                                               throw new AAIException("AAI_6115", "Unrecognized nodeType [" + nodeType + "] passed to node query."); 
+                                       }
+                                       String propName = null;
+                                       String propValue = null;
+                                       if ( pieces.length >= 3) {
+                                               propName = this.findDbPropName(otherNode, pieces[2].toLowerCase());
+                                               propValue = pieces[3];
+                                       }
+                                       String[] edgeLabels = getEdgeLabel(targetNodeType, nodeType);
+                                       
+                                       GraphTraversal<Vertex, Vertex> edgeSearch = __.start();
+                                       
+                                       edgeSearch.both(edgeLabels);
+                                       if (propName != null) {
+                                               // check for matching property
+                                               if (propValue != null) {
+                                                       edgeSearch.has(propName, propValue);
+                                               } else {
+                                                       edgeSearch.has(propName);
+                                               }
+                                       }
+                                       
+                                       if( filterType.equals(DOES_NOT_EXIST)){
+                                               traversal.where(__.not(edgeSearch));
+                                       } else if (filterType.equals(EXISTS)) {
+                                               traversal.where(edgeSearch);
+                                       }
+                               }
+                       }
+
+                       List<Vertex> results = traversal.toList();
+                       Introspector searchResults = loader.introspectorFromName("search-results");
+                       List<Object> resultDataList = searchResults.getValue("result-data");
+                       for (Vertex thisNode: results){
+                               String nodeType = thisNode.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+                               
+                               String thisNodeURL = urlBuilder.pathed(thisNode);
+                               Introspector resultData = loader.introspectorFromName("result-data");
+                               
+                               resultData.setValue("resource-type", nodeType);
+                               resultData.setValue("resource-link", thisNodeURL);
+                               resultDataList.add(resultData.getUnderlyingObject());
+                               
+                       }
+
+                       String outputMediaType = getMediaType(headers.getAcceptableMediaTypes());
+                       org.openecomp.aai.introspection.MarshallerProperties properties = new org.openecomp.aai.introspection.MarshallerProperties.Builder(
+                                       org.openecomp.aai.restcore.MediaType.getEnum(outputMediaType)).build();
+
+                       result = searchResults.marshal(properties);
+                       response = Response.ok().entity(result).build();
+
+                       success = true;
+               } catch (AAIException e) { 
+                       success = false;
+                       throw e;
+               } catch (Exception e) {
+                       success = false;
+                       throw new AAIException("AAI_5105", e);
+               } finally {
+                       if (dbEngine != null) {
+                               if (success) {
+                                       dbEngine.commit();
+                               } else {
+                                       dbEngine.rollback();
+                               }
+                       }
+               }
+
+               return response;        
+       }
+
+       private String findDbPropName(Introspector obj, String propName) {
+               
+               Optional<String> result = obj.getPropertyMetadata(propName, PropertyMetadata.DB_ALIAS);
+               if (result.isPresent()) {
+                       return result.get();
+               } else {
+                       return propName;
+               }
+       }
+       
+
+       /**
+        * Gets the edge label.
+        *
+        * @param targetNodeType the target node type
+        * @param nodeType the node type
+        * @return the edge label
+        * @throws AAIException the AAI exception
+        */
+       public static String[] getEdgeLabel(String targetNodeType, String nodeType) throws AAIException{
+               Map<String, EdgeRule> rules = EdgeRules.getInstance().getEdgeRules(targetNodeType, nodeType);
+               String[] results = rules.keySet().toArray(new String[0]);
+               return results;
+       }
+
+
+       /**
+        * Run named query.
+        *
+        * @param fromAppId the from app id
+        * @param transId the trans id
+        * @param queryParameters the query parameters
+        * @param aaiExtMap the aai ext map
+        * @return the response
+        * @throws JAXBException the JAXB exception
+        * @throws AAIException the AAI exception
+        */
+       public Response runNamedQuery(String fromAppId, String transId, String queryParameters,
+                       DBConnectionType connectionType,
+                       AAIExtensionMap aaiExtMap) throws JAXBException, AAIException {
+               // TODO Auto-generated method stub
+               AAIResources aaiResources = org.openecomp.aai.ingestModel.IngestModelMoxyOxm.aaiResourceContainer
+                               .get(aaiExtMap.getApiVersion());
+               DynamicJAXBContext jaxbContext = aaiResources.getJaxbContext();
+               JAXBUnmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+
+               //String dynamicClass = aaiRes.getResourceClassName();
+
+               Introspector inventoryItems;
+               boolean success = true;
+               TitanTransaction g = null;
+               TransactionalGraphEngine dbEngine = null;
+               try {
+                       
+                       Loader loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, AAIProperties.LATEST);
+                       dbEngine = new TitanDBEngine(
+                                       QueryStyle.TRAVERSAL,
+                                       connectionType,
+                                       loader);
+                       DBSerializer serializer = new DBSerializer(AAIProperties.LATEST, dbEngine, ModelType.MOXY, fromAppId);
+                       ModelBasedProcessing processor = new ModelBasedProcessing(loader, dbEngine, serializer);
+
+                       g = dbEngine.startTransaction();
+                       if (aaiExtMap.getHttpServletRequest().getContentType() == null || // default to json
+                                       aaiExtMap.getHttpServletRequest().getContentType().contains("application/json")) {
+                               unmarshaller.setProperty("eclipselink.media-type", "application/json");
+                               unmarshaller.setProperty("eclipselink.json.include-root", false);
+                       }
+
+                       if (queryParameters.length() == 0) { 
+                               queryParameters = "{}";
+                               unmarshaller.setProperty("eclipselink.media-type", "application/json");
+                               unmarshaller.setProperty("eclipselink.json.include-root", false);
+                       }
+                       String dynamicClass = "inventory.aai.ecomp.org." + aaiExtMap.getApiVersion() + ".ModelAndNamedQuerySearch";
+                       Class<? extends DynamicEntity> resultClass = jaxbContext.newDynamicEntity(dynamicClass).getClass();
+
+                       StringReader reader = new StringReader(queryParameters);
+
+                       DynamicEntity modelAndNamedQuerySearch = (DynamicEntity) unmarshaller.unmarshal(new StreamSource(reader), resultClass).getValue();
+
+                       if (modelAndNamedQuerySearch == null) { 
+                               throw new AAIException("AAI_5105");
+                       }
+
+                       HashMap<String,Object> namedQueryLookupHash = new HashMap<String,Object>();
+
+                       DynamicEntity qp = modelAndNamedQuerySearch.get("queryParameters");
+
+                       String namedQueryUuid = null;
+                       if (qp.isSet("namedQuery")) { 
+                               DynamicEntity namedQuery = (DynamicEntity) qp.get("namedQuery");
+
+                               if (namedQuery.isSet("namedQueryUuid")) { 
+                                       namedQueryUuid = namedQuery.get("namedQueryUuid");
+                               }
+                               if (namedQuery.isSet("namedQueryName")) { 
+                                       namedQueryLookupHash.put("named-query-name",  namedQuery.get("namedQueryName"));
+                               }
+                               if (namedQuery.isSet("namedQueryVersion")) { 
+                                       namedQueryLookupHash.put("named-query-version", namedQuery.get("namedQueryVersion"));
+                               }
+                       }
+
+                       if (namedQueryUuid == null) { 
+
+                               DbMethHelper dbMethHelper = new DbMethHelper(loader, dbEngine);
+                               List<Vertex> namedQueryVertices = dbMethHelper.locateUniqueVertices("named-query", namedQueryLookupHash);
+                               for (Vertex vert : namedQueryVertices) { 
+                                       namedQueryUuid = vert.<String>property("named-query-uuid").orElse(null); 
+                                       // there should only be one, we'll pick the first if not
+                                       break;
+                               }
+                       }
+                       
+                       String secondaryFilterCutPoint = null;
+                       
+                       if (modelAndNamedQuerySearch.isSet("secondaryFilterCutPoint")) { 
+                               secondaryFilterCutPoint = modelAndNamedQuerySearch.get("secondaryFilterCutPoint");
+                       }
+                       
+                       List<Map<String,Object>> startNodeFilterHash = new ArrayList<>();
+
+                       mapInstanceFilters((DynamicEntity)modelAndNamedQuerySearch.get("instanceFilters"), 
+                                       startNodeFilterHash, jaxbContext);                      
+
+                       Map<String,Object> secondaryFilterHash = new HashMap<>();
+                       
+                       mapSecondaryFilters((DynamicEntity)modelAndNamedQuerySearch.get("secondaryFilts"), 
+                                       secondaryFilterHash, jaxbContext);                      
+                       
+                       List<ResultSet> resultSet = processor.queryByNamedQuery(transId, fromAppId,
+                                       namedQueryUuid, startNodeFilterHash, aaiExtMap.getApiVersion(), secondaryFilterCutPoint, secondaryFilterHash);
+
+                       inventoryItems = loader.introspectorFromName("inventory-response-items");
+
+                       List<Object> invItemList = unpackResultSet(resultSet, dbEngine, loader, serializer);
+
+                       inventoryItems.setValue("inventory-response-item", invItemList);
+                       success = true;
+               } catch (AAIException e) {
+                       success = false;
+                       throw e;
+               } catch (Exception e) {
+                       success = false;
+                       throw new AAIException("AAI_5105", e);
+               } finally {
+                       if (g != null) {
+                               if (success) {
+                                       g.commit();
+                               } else {
+                                       g.rollback();
+                               }
+                       }
+               }
+
+               return getResponseFromIntrospector(inventoryItems, aaiExtMap.getHttpHeaders());
+       }
+
+
+       /**
+        * Execute model operation.
+        *
+        * @param fromAppId the from app id
+        * @param transId the trans id
+        * @param queryParameters the query parameters
+        * @param isDelete the is delete
+        * @param aaiExtMap the aai ext map
+        * @return the response
+        * @throws JAXBException the JAXB exception
+        * @throws AAIException the AAI exception
+        * @throws DynamicException the dynamic exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public Response executeModelOperation(String fromAppId, String transId, String queryParameters,
+                       DBConnectionType connectionType,
+                       boolean isDelete,
+                       AAIExtensionMap aaiExtMap) throws JAXBException, AAIException, DynamicException, UnsupportedEncodingException {
+               // TODO Auto-generated method stub
+               AAIResources aaiResources = org.openecomp.aai.ingestModel.IngestModelMoxyOxm.aaiResourceContainer
+                               .get(aaiExtMap.getApiVersion());
+               DynamicJAXBContext jaxbContext = aaiResources.getJaxbContext();
+               JAXBUnmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+
+               //String dynamicClass = aaiRes.getResourceClassName();
+               Response response;
+               boolean success = true;
+               TitanTransaction g = null;
+               TransactionalGraphEngine dbEngine = null;
+               try {
+                       
+                       Loader loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, AAIProperties.LATEST);
+                       dbEngine = new TitanDBEngine(
+                                       QueryStyle.TRAVERSAL,
+                                       connectionType,
+                                       loader);
+                       DBSerializer serializer = new DBSerializer(AAIProperties.LATEST, dbEngine, ModelType.MOXY, fromAppId);
+                       ModelBasedProcessing processor = new ModelBasedProcessing(loader, dbEngine, serializer);
+                       g = dbEngine.startTransaction();
+
+
+                       if (aaiExtMap.getHttpServletRequest().getContentType() == null || // default to json
+                                       aaiExtMap.getHttpServletRequest().getContentType().contains("application/json")) {
+                               unmarshaller.setProperty("eclipselink.media-type", "application/json");
+                               unmarshaller.setProperty("eclipselink.json.include-root", false);
+                       }
+
+                       if (queryParameters.length() == 0) { 
+                               queryParameters = "{}";
+                               unmarshaller.setProperty("eclipselink.media-type", "application/json");
+                               unmarshaller.setProperty("eclipselink.json.include-root", false);
+                       }
+                       String dynamicClass = "inventory.aai.openecomp.org." + aaiExtMap.getApiVersion() + ".ModelAndNamedQuerySearch";
+                       Class<? extends DynamicEntity> resultClass = jaxbContext.newDynamicEntity(dynamicClass).getClass();
+
+                       StringReader reader = new StringReader(queryParameters);
+
+                       DynamicEntity modelAndNamedQuerySearch = (DynamicEntity) unmarshaller.unmarshal(new StreamSource(reader), resultClass).getValue();
+
+                       if (modelAndNamedQuerySearch == null) { 
+                               throw new AAIException("AAI_5105");
+                       }
+
+                       Map<String,Object> modelQueryLookupHash = new HashMap<>();
+                       
+                       String modelVersionId = null;
+                       String modelName = null;
+                       String modelInvariantId = null;
+                       String modelVersion = null;
+                       String topNodeType = null;
+
+                       if (modelAndNamedQuerySearch.isSet("topNodeType")) { 
+                               topNodeType = modelAndNamedQuerySearch.get("topNodeType");
+                       }
+                       
+                       // the ways to get a model:
+                       
+                       // 1.  model-version-id (previously model-name-version-id
+                       // 2.  model-invariant-id (previously model-id) + model-version
+                       // 3.  model-name + model-version
+                                       
+                       // we will support both using the OverloadedModel object in the v9 oxm.  This allows us to unmarshal
+                       // either an old-style model or new-style model + model-ver object
+                       if (modelAndNamedQuerySearch.isSet("queryParameters")) { 
+                               DynamicEntity qp = modelAndNamedQuerySearch.get("queryParameters");
+
+                               if (qp.isSet("model")) { 
+                                       DynamicEntity model = (DynamicEntity) qp.get("model");
+
+                                       // on an old-style model object, the following 4 attrs were all present
+                                       if (model.isSet("modelNameVersionId")) { 
+                                               modelVersionId = model.get("modelNameVersionId");
+                                       }
+                                       if (model.isSet("modelId")) { 
+                                               modelInvariantId =  model.get("modelId");
+                                       }
+                                       if (model.isSet("modelName")) {
+                                               modelName = model.get("modelName");
+                                       }
+                                       if (model.isSet("modelVersion")) { 
+                                               modelVersion =  model.get("modelVersion");
+                                       }
+
+                                       // new style splits model-invariant-id from the other 3 attrs.  This is 
+                                       // the only way to directly look up the model object
+                                       if (model.isSet("modelInvariantId")) { 
+                                               modelInvariantId =  model.get("modelInvariantId");
+                                       }
+                                                               
+                                       if (model.isSet("modelVers")) {
+                                               // we know that this is new style, because modelVers was not an option
+                                               // before v9
+                                               DynamicEntity modelVers = (DynamicEntity) model.get("modelVers");
+                                               if (modelVers.isSet("modelVer")) {
+                                                       List<DynamicEntity> modelVerList = modelVers.get("modelVer");
+                                                       // if they send more than one, too bad, they get the first one
+                                                       DynamicEntity modelVer = modelVerList.get(0);
+                                                       if (modelVer.isSet("modelName")) {
+                                                               modelName = modelVer.get("modelName");
+                                                       }
+                                                       if (modelVer.isSet("modelVersionId")) { 
+                                                               modelVersionId =  modelVer.get("modelVersionId");
+                                                       }
+                                                       if (modelVer.isSet("modelVersion")) { 
+                                                               modelVersion =  modelVer.get("modelVersion");
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       List<Map<String,Object>> startNodeFilterHash = new ArrayList<>();
+
+                       String resourceVersion = mapInstanceFilters((DynamicEntity)modelAndNamedQuerySearch.get("instanceFilters"), 
+                                       startNodeFilterHash, jaxbContext);      
+
+                       if (isDelete) {
+
+                               List<ResultSet> resultSet = processor.queryByModel(transId, fromAppId,
+                                               modelVersionId, modelInvariantId, modelName, topNodeType, startNodeFilterHash, aaiExtMap.getApiVersion() );
+
+                               Map<Object,String> objectToVertMap = new HashMap<>();
+                               List<Object> invItemList = unpackResultSet(resultSet, dbEngine, loader, serializer);
+
+                               ResultSet rs = resultSet.get(0);
+
+                               TitanVertex firstVert = rs.getVert();
+                               String restURL = RestURL.get(g, firstVert);
+
+                               Map<String,String> delResult = processor.runDeleteByModel( transId, fromAppId,
+                                               modelVersionId, topNodeType, startNodeFilterHash.get(0), aaiExtMap.getApiVersion(), resourceVersion );
+
+                               String resultStr = "";
+                               for (Map.Entry<String,String> ent : delResult.entrySet()) { 
+                                       resultStr += "v[" + ent.getKey() + "] " + ent.getValue() + ",\n";
+                               }
+                               resultStr.trim();
+
+                               DynamicEntity inventoryItems = jaxbContext.newDynamicEntity("inventory.aai.openecomp.org." + aaiExtMap.getApiVersion() + ".InventoryResponseItems");
+                               DynamicEntity topInvItem = remapInventoryItems((DynamicEntity)invItemList.get(0), jaxbContext, delResult, objectToVertMap, aaiExtMap);
+
+                               List<DynamicEntity> newInvItemList = new ArrayList<DynamicEntity>();
+                               newInvItemList.add(topInvItem);
+                               inventoryItems.set("inventoryResponseItem", newInvItemList);
+
+                               // put the inventoryItems in a UEB notification object
+                               String notificationVersion = AAIConfig.get("aai.notification.current.version");
+
+                               AAIResources aaiNotificationResources = org.openecomp.aai.ingestModel.IngestModelMoxyOxm.aaiResourceContainer
+                                               .get(notificationVersion);
+
+                               DynamicJAXBContext notificationJaxbContext = aaiNotificationResources.getJaxbContext();
+
+                               DynamicEntity notificationHeader = notificationJaxbContext
+                                               .getDynamicType("inventory.aai.openecomp.org." + notificationVersion + ".NotificationEventHeader")
+                                               .newDynamicEntity();
+
+                               notificationHeader.set("entityLink", restURL);
+                               notificationHeader.set("action", "DELETE");     
+
+                               notificationHeader.set("entityType", "inventory-response-items");
+                               notificationHeader.set("topEntityType", "inventory-response-items");
+                               notificationHeader.set("sourceName", aaiExtMap.getFromAppId());
+                               notificationHeader.set("version", notificationVersion);
+
+                               StoreNotificationEvent sne = new StoreNotificationEvent();
+
+                               sne.storeDynamicEvent(notificationJaxbContext, notificationVersion, notificationHeader, inventoryItems);
+
+                               response = Response.ok(resultStr).build();
+
+                       } else {
+                               List<ResultSet> resultSet = processor.queryByModel( transId, fromAppId,
+                                               modelVersionId, modelInvariantId, modelName, topNodeType, startNodeFilterHash, aaiExtMap.getApiVersion() );
+
+                               Introspector inventoryItems = loader.introspectorFromName("inventory-response-items");
+
+                               List<Object> invItemList = unpackResultSet(resultSet, dbEngine, loader, serializer);
+
+                               inventoryItems.setValue("inventory-response-item", invItemList);
+
+                               response = getResponseFromIntrospector(inventoryItems, aaiExtMap.getHttpHeaders());
+                       }
+                       success = true;
+               } catch (AAIException e) {
+                       success = false;
+                       throw e;
+               } catch (Exception e) {
+                       success = false;
+                       throw new AAIException("AAI_5105", e);
+               } finally {
+                       if (g != null) {
+                               if (success) {
+                                       g.commit();
+                               } else {
+                                       g.rollback();
+                               }
+                       }
+               }
+
+               return response;
+       }
+       
+       private Response getResponseFromIntrospector(Introspector obj, HttpHeaders headers) {
+               boolean isJson = false;
+               for (MediaType mt : headers.getAcceptableMediaTypes()) {
+                       if (MediaType.APPLICATION_JSON_TYPE.isCompatible(mt)) {
+                               isJson = true;
+                               break;
+                       }
+               }
+               org.openecomp.aai.introspection.MarshallerProperties properties;
+               if (isJson) {
+                       properties = 
+                                       new org.openecomp.aai.introspection.MarshallerProperties.Builder(org.openecomp.aai.restcore.MediaType.APPLICATION_JSON_TYPE).build();
+               } else {
+                       properties = 
+                                       new org.openecomp.aai.introspection.MarshallerProperties.Builder(org.openecomp.aai.restcore.MediaType.APPLICATION_XML_TYPE).build();
+               }
+               
+               String marshalledObj = obj.marshal(properties);
+               return Response.ok().entity(marshalledObj).build();
+       }
+
+       /**
+        * Map instance filters.
+        *
+        * @param instanceFilters the instance filters
+        * @param startNodeFilterHash the start node filter hash
+        * @param jaxbContext the jaxb context
+        * @return the string
+        */
+       private String mapInstanceFilters(DynamicEntity instanceFilters, List<Map<String,Object>> startNodeFilterHash, DynamicJAXBContext jaxbContext) {                        
+
+               if (instanceFilters == null || !instanceFilters.isSet("instanceFilter")) {
+                       return null;
+               }
+               @SuppressWarnings("unchecked")
+               List<DynamicEntity> instanceFilter = (ArrayList<DynamicEntity>)instanceFilters.get("instanceFilter");
+               String resourceVersion = null;
+
+               for (DynamicEntity instFilt : instanceFilter) { 
+                       List<DynamicEntity> any = instFilt.get("any");
+                       HashMap<String,Object> thisNodeFilterHash = new HashMap<String,Object>();
+                       for (DynamicEntity anyEnt : any) { 
+                               String clazz = anyEnt.getClass().getCanonicalName();
+                               String simpleClazz = anyEnt.getClass().getSimpleName();
+
+                               String nodeType = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, simpleClazz);
+
+                               DynamicType anyEntType = jaxbContext.getDynamicType(clazz);
+
+                               for (String propName : anyEntType.getPropertiesNames()) {
+                                       // hyphencase the prop and throw it on the hash
+                                       if (anyEnt.isSet(propName)) {
+                                               thisNodeFilterHash.put(nodeType + "." + CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, propName), anyEnt.get(propName));
+                                               if (propName.equals("resourceVersion") && resourceVersion == null) { 
+                                                       resourceVersion = (String)anyEnt.get(propName);
+                                               }
+                                       }
+                               }
+                       }
+                       startNodeFilterHash.add(thisNodeFilterHash);
+               }
+               return resourceVersion;
+       }
+
+       /**
+        * Map secondary filters.
+        *
+        * @param secondaryFilts the secondary filters
+        * @param secondaryFilterHash the secondary filter hash
+        * @param jaxbContext the jaxb context
+        * @return the string
+        */
+       private void mapSecondaryFilters(DynamicEntity secondaryFilts, Map<String,Object> secondaryFilterHash, DynamicJAXBContext jaxbContext) {                        
+
+               if (secondaryFilts == null || !secondaryFilts.isSet("secondaryFilt")) {
+                       return;
+               }
+               @SuppressWarnings("unchecked")
+               List<DynamicEntity> secondaryFilter = (ArrayList<DynamicEntity>)secondaryFilts.get("secondaryFilt");
+               
+               for (DynamicEntity secondaryFilt : secondaryFilter) { 
+                       List<DynamicEntity> any = secondaryFilt.get("any");
+                       
+                       for (DynamicEntity anyEnt : any) { 
+                               String clazz = anyEnt.getClass().getCanonicalName();
+                               String simpleClazz = anyEnt.getClass().getSimpleName();
+
+                               String nodeType = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, simpleClazz);
+
+                               DynamicType anyEntType = jaxbContext.getDynamicType(clazz);
+
+                               for (String propName : anyEntType.getPropertiesNames()) {
+                                       // hyphencase the prop and throw it on the hash
+                                       if (anyEnt.isSet(propName)) {
+                                               secondaryFilterHash.put(nodeType + "." + CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, propName), anyEnt.get(propName));
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * Remap inventory items.
+        *
+        * @param invResultItem the inv result item
+        * @param jaxbContext the jaxb context
+        * @param includeTheseVertices the include these vertices
+        * @param objectToVertMap the object to vert map
+        * @param aaiExtMap the aai ext map
+        * @return the dynamic entity
+        */
+       private DynamicEntity remapInventoryItems(DynamicEntity invResultItem, DynamicJAXBContext jaxbContext, 
+                       Map<String,String> includeTheseVertices, Map<Object,String> objectToVertMap, AAIExtensionMap aaiExtMap) { 
+
+
+               DynamicEntity inventoryItem = jaxbContext.newDynamicEntity("inventory.aai.ecomp.org." + aaiExtMap.getApiVersion() + ".InventoryResponseItem");
+               Object item = invResultItem.get("item");
+               inventoryItem.set("modelName",                  invResultItem.get("modelName"));
+               inventoryItem.set("item",                               item);
+               inventoryItem.set("extraProperties",    invResultItem.get("extraProperties"));
+
+               String vertexId = "";
+
+               if (objectToVertMap.containsKey(item)) {
+                       vertexId = objectToVertMap.get(item);
+               }
+
+               if (includeTheseVertices.containsKey(vertexId)) { 
+                       if (invResultItem.isSet("inventoryResponseItems")) {
+                               List<DynamicEntity> invItemList = new ArrayList<DynamicEntity>();
+                               DynamicEntity inventoryItems = jaxbContext.newDynamicEntity("inventory.aai.ecomp.org." + aaiExtMap.getApiVersion() + ".InventoryResponseItems");
+                               DynamicEntity subInventoryResponseItems = invResultItem.get("inventoryResponseItems");
+                               List<DynamicEntity> subInventoryResponseItemList = subInventoryResponseItems.get("inventoryResponseItem");
+                               for (DynamicEntity ent : subInventoryResponseItemList) { 
+                                       DynamicEntity invItem = remapInventoryItems(ent, jaxbContext, includeTheseVertices, objectToVertMap, aaiExtMap);
+                                       if (invItem != null) { 
+                                               invItemList.add(invItem);
+                                       }
+                               }
+                               if (invItemList != null) { 
+                                       inventoryItems.set("inventoryResponseItem", invItemList);
+                                       inventoryItem.set("inventoryResponseItems",  inventoryItems);
+                               }
+                       }
+               }
+               return inventoryItem;
+       }
+
+       /**
+        * Unpack result set.
+        *
+        * @param g the g
+        * @param resultSetList the result set list
+        * @param jaxbContext the jaxb context
+        * @param aaiResources the aai resources
+        * @param objectToVertMap the object to vert map
+        * @param aaiExtMap the aai ext map
+        * @return the array list
+        * @throws AAIException the AAI exception
+        */
+       // this should return an inventoryItem
+       private List<Object> unpackResultSet(List<ResultSet> resultSetList,
+                       TransactionalGraphEngine engine,
+                       Loader loader,
+                       DBSerializer serializer) throws AAIException {
+
+               List<Object> resultList = new ArrayList<>();
+
+               for (ResultSet resultSet : resultSetList) { 
+                       
+                       if( resultSet.getVert() == null ){
+                               continue;
+                       }
+
+                       Introspector inventoryItem = loader.introspectorFromName("inventory-response-item");
+                       Introspector inventoryItems = loader.introspectorFromName("inventory-response-items");
+                       // add this inventoryItem to the resultList for this level
+                       resultList.add(inventoryItem.getUnderlyingObject());
+
+                       TitanVertex vert = resultSet.getVert();
+
+                       Long vertId = (Long)vert.longId();
+
+                       String aaiNodeType = vert.<String>property("aai-node-type").orElse(null);
+
+                       
+                               
+                       PojoUtils pu = new PojoUtils();
+                       if (aaiNodeType != null) {
+                               Introspector thisObj = loader.introspectorFromName(aaiNodeType);
+
+                               if (resultSet.getExtraPropertyHash() != null) { 
+                                       Map<String,Object> extraProperties = resultSet.getExtraPropertyHash();  
+
+                                       Introspector extraPropertiesEntity = loader.introspectorFromName("extra-properties");
+
+                                       List<Object> extraPropsList = extraPropertiesEntity.getValue("extra-property");
+
+                                       for (Map.Entry<String,Object> ent : extraProperties.entrySet()) {
+                                               String propName = ent.getKey();
+                                               Object propVal = ent.getValue();
+
+                                               Introspector extraPropEntity = loader.introspectorFromName("extra-property");
+
+                                               extraPropEntity.setValue("property-name",  propName);
+                                               extraPropEntity.setValue("property-value", propVal);
+
+                                               extraPropsList.add(extraPropEntity.getUnderlyingObject());
+
+                                       }
+                                       inventoryItem.setValue("extra-properties", extraPropertiesEntity.getUnderlyingObject());
+                               }
+                               
+                               try {
+                                       serializer.dbToObject(Collections.singletonList(vert), thisObj, 0, true, "false");
+                               } catch (UnsupportedEncodingException  e1) {
+                                       throw new AAIException("AAI_5105");
+                               }
+                               PropertyLimitDesc propertyLimitDesc = resultSet.getPropertyLimitDesc();
+
+                               if (propertyLimitDesc != null) {
+
+                                       if (PropertyLimitDesc.SHOW_NONE.equals(propertyLimitDesc)) {
+                                               HashMap<String,Object> emptyPropertyOverRideHash = new HashMap<String,Object>();
+                                               for (String key : thisObj.getAllKeys()) {
+                                                       emptyPropertyOverRideHash.put(key, null);
+                                               }
+                                               filterProperties(thisObj, emptyPropertyOverRideHash);
+                                       } else if (PropertyLimitDesc.SHOW_ALL.equals(propertyLimitDesc)) { 
+                                               //keep everything
+                                       } else if (PropertyLimitDesc.SHOW_NAME_AND_KEYS_ONLY.equals(propertyLimitDesc)) {
+                                               HashMap<String,Object> keysAndNamesPropHash = new HashMap<String,Object>();
+                                               
+                                               for (String key : thisObj.getAllKeys()) {
+                                                       keysAndNamesPropHash.put(key, null);
+                                               }
+                                               String namePropMetaData = thisObj.getMetadata(ObjectMetadata.NAME_PROPS);
+                                               if (namePropMetaData != null) {
+                                                       String[] nameProps = namePropMetaData.split(",");
+                                                       for (String names : nameProps) {
+                                                               keysAndNamesPropHash.put(names, null);
+                                                       }
+                                               }
+                                               filterProperties(thisObj, keysAndNamesPropHash);
+                                       }
+                               } else { 
+                                       if (resultSet.getPropertyOverRideHash() != null && resultSet.getPropertyOverRideHash().size() > 0) { 
+                                               Map<String,Object> propertyOverRideHash = resultSet.getPropertyOverRideHash();
+                                               if (propertyOverRideHash.containsKey("persona-model-id")) {
+                                                       propertyOverRideHash.remove("persona-model-id");
+                                                       propertyOverRideHash.put("model-invariant-id", null);
+                                               }
+                                               for (String key : thisObj.getAllKeys()) {
+                                                       propertyOverRideHash.put(key, null);
+                                               }
+                                               filterProperties(thisObj, propertyOverRideHash);
+                                       } else {
+                                               //keep everything
+                                       }
+                               }
+
+                               if (thisObj != null) { 
+                                       inventoryItem.setValue("item", thisObj.getUnderlyingObject());
+
+                                       String modelName = null;
+                                       try { 
+                                               String modelInvariantIdLocal = (String)vert.<String>property("model-invariant-id-local").orElse(null); // this one points at a model
+                                               String modelVersionIdLocal = (String)vert.<String>property("model-version-id-local").orElse(null); // this one points at a model-ver
+                                               
+                                               if ( (modelInvariantIdLocal != null && modelVersionIdLocal != null) 
+                                                               && (modelInvariantIdLocal.length() > 0 && modelVersionIdLocal.length() > 0) ) {
+                                                       HashMap<String,Object> modelLookupHash = new HashMap<String,Object>();
+
+                                                       Introspector modelVer = loader.introspectorFromName("model-ver");
+                                                       modelVer.setValue("model-version-id", modelVersionIdLocal);
+                                                       QueryBuilder builder = engine.getQueryBuilder().createDBQuery(modelVer);
+                                                       
+                                                       List<Vertex> modelVerVerts = builder.toList();
+                                                       if (modelVerVerts.size() != 1) {
+                                                               throw new AAIException("AAI_6112");
+                                                       }
+                                                       Vertex modelVerVert = modelVerVerts.get(0);
+                                                       
+                                                       modelName = modelVerVert.<String>property("model-name").orElse(null); 
+
+                                                       if (modelName != null && modelName.length() > 0) { 
+                                                               inventoryItem.setValue("model-name", modelName);
+                                                       }
+                                               }
+                                       } catch (DynamicException e) { 
+                                               ; // it's ok, dynamic object might not have these fields
+                                       } catch (AAIException e) { 
+                                               if (e.getErrorObject().getErrorCode().equals("6114")) { 
+                                                       // it's ok, couldn't find a matching model
+                                               } else { 
+                                                       throw e;
+                                               }
+                                       }
+                                       
+                                       if (resultSet.getSubResultSet() != null) { 
+                                               List<ResultSet> subResultSet = resultSet.getSubResultSet();
+                                               if (subResultSet != null && subResultSet.size() > 0 ) { 
+                                                       List<Object> res = unpackResultSet(subResultSet, engine, loader, serializer);
+                                                       if (res.size() > 0) { 
+                                                               inventoryItems.setValue("inventory-response-item", res);
+                                                               inventoryItem.setValue("inventory-response-items", inventoryItems.getUnderlyingObject());
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               return resultList;
+       }
+       
+       private void filterProperties(Introspector thisObj, Map<String, Object> override) {
+               
+               thisObj.getProperties().stream().filter(x -> {
+                       return !override.containsKey(x);
+               }).forEach(prop -> {
+                       if (thisObj.isSimpleType(prop)) {
+                               thisObj.setValue(prop, null);
+                       }
+               });
+
+       }
+
+       /**
+        * Gets the media type.
+        *
+        * @param mediaTypeList the media type list
+        * @return the media type
+        */
+       protected String getMediaType(List <MediaType> mediaTypeList) {
+               String mediaType = MediaType.APPLICATION_JSON;  // json is the default
+               for (MediaType mt : mediaTypeList) {
+                       if (MediaType.APPLICATION_XML_TYPE.isCompatible(mt)) {
+                               mediaType = MediaType.APPLICATION_XML;
+                       }
+               }
+               return mediaType;
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/dmaap/AAIDmaapEventJMSConsumer.java b/aai-traversal/src/main/java/org/openecomp/aai/dmaap/AAIDmaapEventJMSConsumer.java
new file mode 100644 (file)
index 0000000..d8a0ce7
--- /dev/null
@@ -0,0 +1,163 @@
+/*-
+ * ============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.dmaap;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.TextMessage;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.log4j.MDC;
+import org.eclipse.jetty.util.security.Password;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.util.AAIConstants;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.nsa.mr.client.MRBatchingPublisher;
+import com.att.nsa.mr.client.MRClientFactory;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
+
+public class AAIDmaapEventJMSConsumer implements MessageListener {
+
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAIDmaapEventJMSConsumer.class);
+
+       private final static String COMPONENT = "aaiDmaapEvent";
+       private MRBatchingPublisher adp = null;
+
+       private Properties props;
+
+       private String username;
+       private String password;
+       private String contentType;
+
+       private String url;
+       private Client client;
+
+       public AAIDmaapEventJMSConsumer() throws org.apache.commons.configuration.ConfigurationException {
+               super();
+
+               if (this.adp == null) {
+                       try {
+                               FileReader reader = new FileReader(new File(AAIConstants.AAI_EVENT_DMAAP_PROPS));
+                               props = new Properties();
+                               props.load(reader);
+                               props.setProperty("DME2preferredRouterFilePath", AAIConstants.AAI_HOME_ETC_APP_PROPERTIES + "preferredRoute.txt");
+                               if (props.getProperty("password") != null && props.getProperty("password").startsWith("OBF:")) {
+                                       props.setProperty("password", Password.deobfuscate(props.getProperty("password")));
+                               }
+                               this.adp = MRClientFactory.createBatchingPublisher(props);
+
+                               String host = props.getProperty("host");
+                               String topic = props.getProperty("topic");
+                               String protocol = props.getProperty("Protocol");
+
+                               username = props.getProperty("username");
+                               password = props.getProperty("password");
+                               contentType = props.getProperty("contenttype");
+
+                               url = protocol + "://" + host + "/events/" + topic;
+                               client = Client.create();
+                               client.addFilter(new HTTPBasicAuthFilter(username, password));
+
+                       } catch (IOException e) {
+                               ErrorLogHelper.logError("AAI_4000", "Error updating dmaap config file for aai event.");
+                       }
+               }
+
+       }
+
+       @Override
+       public void onMessage(Message message) {
+
+               String jsmMessageTxt = "";
+               String aaiEvent = "";
+               String transId = "";
+               String fromAppId = "";
+               String fullId = "";
+
+               if (message instanceof TextMessage) {
+                       try {
+                               jsmMessageTxt = ((TextMessage) message).getText();
+                               JSONObject jo = new JSONObject(jsmMessageTxt);
+
+                               if (jo.has("aaiEventPayload")) {
+                                       aaiEvent = jo.getJSONObject("aaiEventPayload").toString();
+                               } else {
+                                       return;
+                               }
+                               if (jo.getString("transId") != null) {
+                                       MDC.put("requestId", jo.getString("transId"));
+                               }
+                               if (jo.getString("fromAppId") != null) {
+                                       MDC.put("partnerName", jo.getString("fromAppId"));
+                               }
+                               if (jo.getString("fullId") != null) {
+                                       fullId = jo.getString("fullId");
+                               }
+
+                               LOGGER.info(fullId + "|" + transId + "|" + fromAppId + "|" + aaiEvent);
+
+                               String environment = System.getProperty("lrmRO");
+
+                               if (environment == null) {
+                                       this.adp.send(aaiEvent);
+                               } else {
+                                       if (environment.startsWith("dev") || environment.startsWith("testINT") || environment.startsWith("testEXT")) {
+
+                                               WebResource webResource = client.resource(url);
+
+                                               ClientResponse response = webResource.accept(contentType).type(MediaType.APPLICATION_JSON).post(ClientResponse.class, aaiEvent);
+
+                                               if (response.getStatus() != 200) {
+                                                       System.out.println("Failed : HTTP error code : " + response.getStatus());
+                                               }
+                                       } else {
+                                               this.adp.send(aaiEvent);
+                                       }
+                               }
+
+                       } catch (IOException e) {
+                               if (e instanceof java.net.SocketException) {
+                                       if (e.getMessage().contains("Connection reset")) {
+                                       } else {
+                                               ErrorLogHelper.logError("AAI_7304", "Error reaching DMaaP to send event. " + aaiEvent);
+                                       }
+                               } else {
+                                       ErrorLogHelper.logError("AAI_7304", "Error reaching DMaaP to send event. " + aaiEvent);
+                               }
+                       } catch (JMSException | JSONException e) {
+                               ErrorLogHelper.logError("AAI_7350", "Error parsing aaievent jsm message for sending to dmaap. " + jsmMessageTxt);
+                       }
+               }
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/dmaap/AAIDmaapEventJMSProducer.java b/aai-traversal/src/main/java/org/openecomp/aai/dmaap/AAIDmaapEventJMSProducer.java
new file mode 100644 (file)
index 0000000..305e585
--- /dev/null
@@ -0,0 +1,44 @@
+/*-
+ * ============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.dmaap;
+
+import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.activemq.command.ActiveMQQueue;
+import org.json.JSONObject;
+import org.springframework.jms.connection.CachingConnectionFactory;
+import org.springframework.jms.core.JmsTemplate;
+
+public class AAIDmaapEventJMSProducer {
+
+       private JmsTemplate jmsTemplate;
+
+       public AAIDmaapEventJMSProducer() {
+               this.jmsTemplate = new JmsTemplate();
+               this.jmsTemplate.setConnectionFactory(new CachingConnectionFactory(new ActiveMQConnectionFactory("tcp://localhost:61446")));
+               this.jmsTemplate.setDefaultDestination(new ActiveMQQueue("IN_QUEUE"));
+       }
+
+       public void sendMessageToDefaultDestination(JSONObject finalJson) {
+               jmsTemplate.convertAndSend(finalJson.toString());
+               CachingConnectionFactory ccf = (CachingConnectionFactory)this.jmsTemplate.getConnectionFactory();
+               ccf.destroy();
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/extensions/AAIExtensionMap.java b/aai-traversal/src/main/java/org/openecomp/aai/extensions/AAIExtensionMap.java
new file mode 100644 (file)
index 0000000..167dae4
--- /dev/null
@@ -0,0 +1,827 @@
+/*-
+ * ============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.extensions;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+
+import org.openecomp.aai.domain.responseMessage.AAIResponseMessages;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.rest.db.DBRequest;
+import org.openecomp.aai.rest.db.HttpEntry;
+import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
+import com.thinkaurelius.titan.core.TitanTransaction;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+public class AAIExtensionMap {
+       // =======================================================================
+       // Attribute | Type
+       // =======================================================================
+       // message | java.lang.String (RW)
+       // ----------------------------------------------------------------------
+       // templateVars | java.lang.ArrayList<String> (RW)
+       // -----------------------------------------------------------------------
+       // preExtException | java.lang.Exception (RW)
+       // -----------------------------------------------------------------------
+       // preExtErrorCallback | java.lang.reflect.Method (RW)
+       // -----------------------------------------------------------------------
+       // postExtException | java.lang.Exception (RW)
+       // -----------------------------------------------------------------------
+       // postExtErrorCallback | java.lang.reflect.Method (RW)
+       // -----------------------------------------------------------------------
+       // servletRequest | javax.servlet.http.HttpServletRequest (RO)
+       // -----------------------------------------------------------------------
+       // headers | javax.ws.rs.core.HttpHeaders (RO)
+       // -----------------------------------------------------------------------
+       // objFromRequestType | String (ex. ?org.openecomp.aai.domain.yang.Vce?) (RO)
+       // -----------------------------------------------------------------------
+       // objFromRequest | $TYPE {ObjFromRequestType) (RO)
+       // -----------------------------------------------------------------------
+       // preExtFailOnError | java.lang.Boolean (RW)
+       // -----------------------------------------------------------------------
+       // postExtFailOnError | java.lang.Boolean (RW)
+       // -----------------------------------------------------------------------
+       // preExtSkipErrorCallback | java.lang.Boolean (RW)
+       // -----------------------------------------------------------------------
+       // postExtSkipErrorCallback | java.lang.Boolean (RW)
+       // -----------------------------------------------------------------------
+       // graph | com.thinkaurelius.titan.core.TitanGraph (RW)
+       // -----------------------------------------------------------------------
+       // objectFromResponse | Object
+       // -----------------------------------------------------------------------
+       // precheckAddedList | java.util.HashMap
+       // -----------------------------------------------------------------------
+       // precheckResponseMessages | org.openecomp.aai.extensions.AAIResponseMessages
+       // =======================================================================
+
+       private String message;
+       private ArrayList<String> templateVars;
+       private Exception preExtException;
+       private Exception postExtException;
+       private Method preExtErrorCallback;
+       private Method postExtErrorCallback;
+       private HttpServletRequest servletRequest;
+       private HttpHeaders httpHeaders;
+       private String objectFromRequestType;
+       private Object objectFromRequest;
+       private boolean preExtFailOnError = true;
+       private boolean postExtFailOnError = true;
+       private boolean preExtSkipErrorCallback = true;
+       private boolean postExtSkipErrorCallback = true;
+       private String fromAppId;
+       private String transId;
+       private TitanTransaction graph;
+       private Object objectFromResponse;
+       private HashMap<String, Object> lookupHashMap;
+       private HashMap<String, ArrayList<String>> precheckAddedList;
+       private AAIResponseMessages precheckResponseMessages;
+       private HashMap<String, Object> topology;
+       private HashMap<String, TitanVertex> vertexCache;
+       private String baseObject;
+       private String namespace;
+       private String fullResourceName;
+       private String topObjectFullResourceName;
+       private String uri;
+       private String notificationUri;
+       private String apiVersion;
+       private long startTime;
+       private long checkpointTime;
+       private DynamicJAXBContext jaxbContext;
+       private String objectFromResponseType;
+       private String eventAction;
+       private TransactionalGraphEngine dbEngine;
+       private Loader loader;
+       private UriInfo uriInfo;
+       private DBRequest dbRequest;
+       private HttpEntry httpEntry;
+       /**
+        * Sets the message.
+        *
+        * @param _message the new message
+        */
+       public void setMessage(String _message) {
+               this.message = _message;
+       }
+
+       /**
+        * Sets the template vars.
+        *
+        * @param _templateVars the new template vars
+        */
+       public void setTemplateVars(ArrayList<String> _templateVars) {
+               this.templateVars = _templateVars;
+       }
+
+       /**
+        * Sets the pre ext exception.
+        *
+        * @param _exception the new pre ext exception
+        */
+       public void setPreExtException(Exception _exception) {
+               this.preExtException = _exception;
+       }
+
+       /**
+        * Sets the pre ext error callback.
+        *
+        * @param _errorCallback the new pre ext error callback
+        */
+       public void setPreExtErrorCallback(Method _errorCallback) {
+               this.preExtErrorCallback = _errorCallback;
+       }
+
+       /**
+        * Sets the post ext exception.
+        *
+        * @param _exception the new post ext exception
+        */
+       public void setPostExtException(Exception _exception) {
+               this.postExtException = _exception;
+       }
+
+       /**
+        * Sets the post ext error callback.
+        *
+        * @param _errorCallback the new post ext error callback
+        */
+       public void setPostExtErrorCallback(Method _errorCallback) {
+               this.postExtErrorCallback = _errorCallback;
+       }
+
+       /**
+        * Sets the servlet request.
+        *
+        * @param _httpServletRequest the new servlet request
+        */
+       public void setServletRequest(HttpServletRequest _httpServletRequest) {
+               this.servletRequest = _httpServletRequest;
+       }
+
+       /**
+        * Sets the http headers.
+        *
+        * @param _httpHeaders the new http headers
+        */
+       public void setHttpHeaders(HttpHeaders _httpHeaders) {
+               this.httpHeaders = _httpHeaders;
+       }
+
+       /**
+        * Sets the object from request type.
+        *
+        * @param _objectFromRequestType the new object from request type
+        */
+       public void setObjectFromRequestType(String _objectFromRequestType) {
+               this.objectFromRequestType = _objectFromRequestType;
+       }
+
+       /**
+        * Sets the object from request.
+        *
+        * @param _objectFromRequest the new object from request
+        */
+       public void setObjectFromRequest(Object _objectFromRequest) {
+               this.objectFromRequest = _objectFromRequest;
+       }
+
+       /**
+        * Sets the object from response type.
+        *
+        * @param resourceClassName the new object from response type
+        */
+       public void setObjectFromResponseType(String resourceClassName) {
+               // TODO Auto-generated method stub
+               this.objectFromResponseType = resourceClassName;
+       }
+       
+       /**
+        * Gets the object from response type.
+        *
+        * @return the object from response type
+        */
+       public String getObjectFromResponseType() {
+               // TODO Auto-generated method stub
+               return this.objectFromResponseType;
+       }
+       
+       /**
+        * Sets the pre ext fail on error.
+        *
+        * @param _failOnError the new pre ext fail on error
+        */
+       public void setPreExtFailOnError(boolean _failOnError) {
+               this.preExtFailOnError = _failOnError;
+       }
+
+       /**
+        * Sets the post ext fail on error.
+        *
+        * @param _failOnError the new post ext fail on error
+        */
+       public void setPostExtFailOnError(boolean _failOnError) {
+               this.postExtFailOnError = _failOnError;
+       }
+
+       /**
+        * Gets the message.
+        *
+        * @return the message
+        */
+       public String getMessage() {
+               return this.message;
+       }
+
+       /**
+        * Gets the template vars.
+        *
+        * @return the template vars
+        */
+       public ArrayList<String> getTemplateVars() {
+               if (this.templateVars == null) {
+                       this.templateVars = new ArrayList<String>();
+               }
+               return this.templateVars;
+       }
+
+       /**
+        * Gets the pre ext exception.
+        *
+        * @return the pre ext exception
+        */
+       public Exception getPreExtException() {
+               return this.preExtException;
+       }
+
+       /**
+        * Gets the pre ext error callback.
+        *
+        * @return the pre ext error callback
+        */
+       public Method getPreExtErrorCallback() {
+               return this.preExtErrorCallback;
+       }
+
+       /**
+        * Gets the post ext exception.
+        *
+        * @return the post ext exception
+        */
+       public Exception getPostExtException() {
+               return this.postExtException;
+       }
+
+       /**
+        * Gets the post ext error callback.
+        *
+        * @return the post ext error callback
+        */
+       public Method getPostExtErrorCallback() {
+               return this.postExtErrorCallback;
+       }
+
+       /**
+        * Gets the http servlet request.
+        *
+        * @return the http servlet request
+        */
+       public HttpServletRequest getHttpServletRequest() {
+               return this.servletRequest;
+       }
+
+       /**
+        * Gets the http headers.
+        *
+        * @return the http headers
+        */
+       public HttpHeaders getHttpHeaders() {
+               return this.httpHeaders;
+       }
+
+       /**
+        * Gets the object from request type.
+        *
+        * @return the object from request type
+        */
+       public String getObjectFromRequestType() {
+               return this.objectFromRequestType;
+       }
+
+       /**
+        * Gets the object from request.
+        *
+        * @return the object from request
+        */
+       public Object getObjectFromRequest() {
+               return this.objectFromRequest;
+       }
+
+       /**
+        * Gets the pre ext fail on error.
+        *
+        * @return the pre ext fail on error
+        */
+       public boolean getPreExtFailOnError() {
+               return this.preExtFailOnError;
+       }
+
+       /**
+        * Gets the post ext fail on error.
+        *
+        * @return the post ext fail on error
+        */
+       public boolean getPostExtFailOnError() {
+               return this.postExtFailOnError;
+       }
+
+       /**
+        * Gets the from app id.
+        *
+        * @return the from app id
+        */
+       public String getFromAppId() {
+               return this.fromAppId;
+       }
+
+       /**
+        * Sets the from app id.
+        *
+        * @param fromAppId the new from app id
+        */
+       public void setFromAppId(String fromAppId) {
+               this.fromAppId = fromAppId;
+       }
+
+       /**
+        * Gets the trans id.
+        *
+        * @return the trans id
+        */
+       public String getTransId() {
+               return this.transId;
+       }
+
+       /**
+        * Sets the trans id.
+        *
+        * @param transId the new trans id
+        */
+       public void setTransId(String transId) {
+               this.transId = transId;
+       }
+       
+       /**
+        * Gets the pre ext skip error callback.
+        *
+        * @return the pre ext skip error callback
+        */
+       public boolean getPreExtSkipErrorCallback() {
+               return preExtSkipErrorCallback;
+       }
+
+       /**
+        * Sets the pre ext skip error callback.
+        *
+        * @param preExtSkipErrorCallback the new pre ext skip error callback
+        */
+       public void setPreExtSkipErrorCallback(boolean preExtSkipErrorCallback) {
+               this.preExtSkipErrorCallback = preExtSkipErrorCallback;
+       }
+
+       /**
+        * Gets the post ext skip error callback.
+        *
+        * @return the post ext skip error callback
+        */
+       public boolean getPostExtSkipErrorCallback() {
+               return postExtSkipErrorCallback;
+       }
+
+       /**
+        * Sets the post ext skip error callback.
+        *
+        * @param postExtSkipErrorCallback the new post ext skip error callback
+        */
+       public void setPostExtSkipErrorCallback(boolean postExtSkipErrorCallback) {
+               this.postExtSkipErrorCallback = postExtSkipErrorCallback;
+       }
+
+       /**
+        * Gets the graph.
+        *
+        * @return the graph
+        */
+       public TitanTransaction getGraph() {
+               return graph;
+       }
+
+       /**
+        * Sets the graph.
+        *
+        * @param graph the new graph
+        */
+       public void setGraph(TitanTransaction graph) {
+               this.graph = graph;
+       }
+
+       /**
+        * Gets the object from response.
+        *
+        * @return the object from response
+        */
+       public Object getObjectFromResponse() {
+               return objectFromResponse;
+       }
+
+       /**
+        * Sets the object from response.
+        *
+        * @param objectFromResponse the new object from response
+        */
+       public void setObjectFromResponse(Object objectFromResponse) {
+               this.objectFromResponse = objectFromResponse;
+       }
+
+       /**
+        * Gets the lookup hash map.
+        *
+        * @return the lookup hash map
+        */
+       public HashMap<String, Object> getLookupHashMap() {
+               if (this.lookupHashMap == null) {
+                       this.lookupHashMap = new HashMap<String, Object>();
+               }
+               return this.lookupHashMap;
+       }
+
+       /**
+        * Sets the lookup hash map.
+        *
+        * @param lookupHashMap the lookup hash map
+        */
+       public void setLookupHashMap(HashMap<String, Object> lookupHashMap) {
+               this.lookupHashMap = lookupHashMap;
+       }
+
+       /**
+        * Gets the precheck added list.
+        *
+        * @return the precheck added list
+        */
+       public HashMap<String, ArrayList<String>> getPrecheckAddedList() {
+               if (this.precheckAddedList == null) {
+                       this.precheckAddedList = new HashMap<String, ArrayList<String>>();
+               }
+               return precheckAddedList;
+       }
+
+       /**
+        * Sets the precheck added list.
+        *
+        * @param precheckAddedList the precheck added list
+        */
+       public void setPrecheckAddedList(HashMap<String, ArrayList<String>> precheckAddedList) {
+               this.precheckAddedList = precheckAddedList;
+       }
+
+       /**
+        * Gets the precheck response messages.
+        *
+        * @return the precheck response messages
+        */
+       public AAIResponseMessages getPrecheckResponseMessages() {
+               if (this.precheckResponseMessages == null) { 
+                       this.precheckResponseMessages = new AAIResponseMessages();
+               }
+               return precheckResponseMessages;
+       }
+
+       /**
+        * Sets the precheck response messages.
+        *
+        * @param precheckResponseData the new precheck response messages
+        */
+       public void setPrecheckResponseMessages(AAIResponseMessages precheckResponseData) {
+               this.precheckResponseMessages = precheckResponseData;
+       }
+
+       /**
+        * Gets the topology.
+        *
+        * @return the topology
+        */
+       public HashMap<String, Object> getTopology() {
+               if (this.topology == null) { 
+                       this.topology = new HashMap<String, Object>();
+               }
+               return topology;
+       }
+       
+       /**
+        * Gets the vertex cache.
+        *
+        * @return the vertex cache
+        */
+       public HashMap<String, TitanVertex> getVertexCache() {
+               if (this.vertexCache == null) { 
+                       this.vertexCache = new HashMap<String, TitanVertex>();
+               }
+               return vertexCache;
+       }
+
+       /**
+        * Gets the base object.
+        *
+        * @return the base object
+        */
+       public String getBaseObject() {
+               return baseObject;
+       }
+
+       /**
+        * Sets the base object.
+        *
+        * @param baseObject the new base object
+        */
+       public void setBaseObject(String baseObject) {
+               this.baseObject = baseObject;
+       }
+
+       /**
+        * Gets the namespace.
+        *
+        * @return the namespace
+        */
+       public String getNamespace() {
+               return namespace;
+       }
+
+       /**
+        * Sets the namespace.
+        *
+        * @param namespace the new namespace
+        */
+       public void setNamespace(String namespace) {
+               this.namespace = namespace;
+       }
+
+       /**
+        * Gets the full resource name.
+        *
+        * @return the full resource name
+        */
+       public String getFullResourceName() {
+               return fullResourceName;
+       }
+
+       /**
+        * Sets the full resource name.
+        *
+        * @param fullResourceName the new full resource name
+        */
+       public void setFullResourceName(String fullResourceName) {
+               this.fullResourceName = fullResourceName;
+       }
+
+       /**
+        * Gets the top object full resource name.
+        *
+        * @return the top object full resource name
+        */
+       public String getTopObjectFullResourceName() {
+               return topObjectFullResourceName;
+       }
+
+       /**
+        * Sets the top object full resource name.
+        *
+        * @param topObjectFullResourceName the new top object full resource name
+        */
+       public void setTopObjectFullResourceName(String topObjectFullResourceName) {
+               this.topObjectFullResourceName = topObjectFullResourceName;
+       }
+
+       /**
+        * Gets the uri.
+        *
+        * @return the uri
+        */
+       public String getUri() {
+               return uri;
+       }
+
+       /**
+        * Sets the uri.
+        *
+        * @param uri the new uri
+        */
+       public void setUri(String uri) {
+               this.uri = uri;
+       }
+
+       /**
+        * Gets the api version.
+        *
+        * @return the api version
+        */
+       public String getApiVersion() {
+               return apiVersion;
+       }
+
+       /**
+        * Sets the api version.
+        *
+        * @param apiVersion the new api version
+        */
+       public void setApiVersion(String apiVersion) {
+               this.apiVersion = apiVersion;
+       }
+
+       /**
+        * Sets the notification uri.
+        *
+        * @param uri the new notification uri
+        */
+       public void setNotificationUri(String uri) {
+               this.notificationUri = uri;
+               
+       }
+       
+       /**
+        * Gets the notification uri.
+        *
+        * @return the notification uri
+        */
+       public String getNotificationUri() {
+               return this.notificationUri;
+               
+       }
+
+       /**
+        * Gets the start time.
+        *
+        * @return the start time
+        */
+       public long getStartTime() {
+               return startTime;
+       }
+
+       /**
+        * Sets the start time.
+        *
+        * @param startTime the new start time
+        */
+       public void setStartTime(long startTime) {
+               this.startTime = startTime;
+       }
+
+       /**
+        * Gets the checkpoint time.
+        *
+        * @return the checkpoint time
+        */
+       public long getCheckpointTime() {
+               return checkpointTime;
+       }
+
+       /**
+        * Sets the checkpoint time.
+        *
+        * @param checkpointTime the new checkpoint time
+        */
+       public void setCheckpointTime(long checkpointTime) {
+               this.checkpointTime = checkpointTime;
+       }
+
+       /**
+        * Gets the jaxb context.
+        *
+        * @return the jaxb context
+        */
+       public DynamicJAXBContext getJaxbContext() {
+               return jaxbContext;
+       }
+
+       /**
+        * Sets the jaxb context.
+        *
+        * @param jaxbContext the new jaxb context
+        */
+       public void setJaxbContext(DynamicJAXBContext jaxbContext) {
+               this.jaxbContext = jaxbContext;
+       }
+
+       /**
+        * Sets the event action.
+        *
+        * @param eventAction the new event action
+        */
+       public void setEventAction(String eventAction) {
+               this.eventAction = eventAction;
+       }
+       
+       /**
+        * Gets the event action.
+        *
+        * @return the event action
+        */
+       public String getEventAction() {
+               return this.eventAction;
+       }
+
+       /**
+        * Gets the transactional graph engine.
+        *
+        * @return the transactional graph engine
+        */
+       public TransactionalGraphEngine getTransactionalGraphEngine() {
+               return this.dbEngine;
+               
+       }
+       
+       /**
+        * Sets the transactional graph engine.
+        *
+        * @param dbEngine the new transactional graph engine
+        */
+       public void setTransactionalGraphEngine(TransactionalGraphEngine dbEngine) {
+               this.dbEngine = dbEngine;
+
+       }
+
+       /**
+        * Gets the loader.
+        *
+        * @return the loader
+        */
+       public Loader getLoader() {
+               return loader;
+       }
+
+       /**
+        * Sets the loader.
+        *
+        * @param loader the new loader
+        */
+       public void setLoader(Loader loader) {
+               this.loader = loader;
+       }
+
+       /**
+        * Gets the uri info.
+        *
+        * @return the uri info
+        */
+       public UriInfo getUriInfo() {
+               return uriInfo;
+       }
+
+       /**
+        * Sets the uri info.
+        *
+        * @param uriInfo the new uri info
+        */
+       public void setUriInfo(UriInfo uriInfo) {
+               this.uriInfo = uriInfo;
+       }
+
+       public DBRequest getDbRequest() {
+               return dbRequest;
+       }
+
+       public void setDbRequest(DBRequest dbRequest) {
+               this.dbRequest = dbRequest;
+       }
+
+       public HttpEntry getHttpEntry() {
+               return httpEntry;
+       }
+
+       public void setHttpEntry(HttpEntry httpEntry) {
+               this.httpEntry = httpEntry;
+       }       
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/extensions/ExtensionController.java b/aai-traversal/src/main/java/org/openecomp/aai/extensions/ExtensionController.java
new file mode 100644 (file)
index 0000000..09cfe50
--- /dev/null
@@ -0,0 +1,145 @@
+/*-
+ * ============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.extensions;
+
+import java.lang.reflect.Method;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.util.AAIConfig;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class ExtensionController {
+
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ExtensionController.class);
+
+       /**
+        * Run extension.
+        *
+        * @param apiVersion the api version
+        * @param namespace the namespace
+        * @param resourceName the resource name
+        * @param methodName the method name
+        * @param aaiExtMap the aai ext map
+        * @param isPreExtension the is pre extension
+        * @throws AAIException the AAI exception
+        */
+       public void runExtension(String apiVersion, String namespace,
+                       String resourceName, String methodName, AAIExtensionMap aaiExtMap,
+                       boolean isPreExtension) throws AAIException {
+               String extensionClassName = "org.openecomp.aai.extensions."
+                               + apiVersion.toLowerCase() + "." + namespace + "."
+                               + resourceName + "Extension";
+               String defaultErrorCallback = resourceName + "ExtensionErrorCallback";
+
+               String configOption = "aai.extensions." + apiVersion.toLowerCase()
+                               + "." + namespace.toLowerCase() + "."
+                               + resourceName.toLowerCase() + ".enabled";
+
+               try {
+
+                       String extensionEnabled = AAIConfig.get(configOption, "true");
+                       if (extensionEnabled.equalsIgnoreCase("false")) {
+                               return;
+                       }
+
+                       Class<?> clazz = Class.forName(extensionClassName);
+
+                       Method extension = clazz.getMethod(methodName,
+                                       new Class[] { AAIExtensionMap.class });
+                       if (extension != null) {
+
+                               Object ret = extension.invoke(clazz.newInstance(), aaiExtMap);
+
+                               if (ret instanceof Integer) {
+                                       Exception e = null;
+                                       
+                                       if (isPreExtension == true) {
+                                               e = aaiExtMap.getPreExtException();
+                                       } else {
+                                               e = aaiExtMap.getPostExtException();
+                                       }
+
+                                       boolean failOnError = true;
+                                       if (isPreExtension == true) {
+                                               failOnError = aaiExtMap.getPreExtFailOnError();
+                                       } else {
+                                               failOnError = aaiExtMap.getPostExtFailOnError();
+                                       }
+
+                                       if (e != null) {
+                                               boolean handleException = true;
+                                               if (isPreExtension == true) {
+                                                       if (aaiExtMap.getPreExtSkipErrorCallback() == true) { 
+                                                               handleException = false;
+                                                       }
+                                               } else {
+                                                       if (aaiExtMap.getPostExtSkipErrorCallback() == true) { 
+                                                               handleException = false;
+                                                       }
+                                               }
+                                               if (handleException == true) {
+                                                       Method errorCallback = null;
+                                                       if (isPreExtension == true) {
+                                                               errorCallback = aaiExtMap
+                                                                               .getPreExtErrorCallback();
+                                                       } else {
+                                                               errorCallback = aaiExtMap
+                                                                               .getPostExtErrorCallback();
+                                                       }
+
+                                                       if (errorCallback != null) {
+                                                               errorCallback.invoke(clazz.newInstance(),
+                                                                               aaiExtMap);
+                                                       } else {
+                                                               Method defaultErrorCallbackExtension = clazz
+                                                                               .getMethod(
+                                                                                               defaultErrorCallback,
+                                                                                               new Class[] { AAIExtensionMap.class });
+                                                               defaultErrorCallbackExtension.invoke(
+                                                                               clazz.newInstance(), aaiExtMap);
+                                                       }
+                                               }
+                                       }
+
+                                       if (failOnError == true && e != null) {
+                                               throw e;
+                                       } else if (failOnError == false && e != null) { // in this
+                                                                                                                                       // case, we
+                                                                                                                                       // just note
+                                                                                                                                       // the error
+                                                                                                                                       // without
+                                                                                                                                       // stopping
+                                               LOGGER.warn("Error while processing extension - " + aaiExtMap.getMessage());
+                                       }
+                               }
+                       }
+               } catch (ClassNotFoundException ex) {
+                       LOGGER.debug("Extension class not found: " + extensionClassName + ", method: " + methodName + ".");
+               } catch (NoSuchMethodException e) {
+                       LOGGER.debug("Method " + methodName + " does not exist for class " + extensionClassName); 
+               } catch (AAIException e) {
+                       throw e;
+               } catch (Exception e) {
+                       throw new AAIException("AAI_5105", e);
+               } 
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/interceptors/AAIHeaderProperties.java b/aai-traversal/src/main/java/org/openecomp/aai/interceptors/AAIHeaderProperties.java
new file mode 100644 (file)
index 0000000..4798d90
--- /dev/null
@@ -0,0 +1,26 @@
+/*-
+ * ============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.interceptors;
+
+public class AAIHeaderProperties {
+
+       public static final String REQUEST_CONTEXT = "aai-request-context";
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/interceptors/AAILogJAXRSInInterceptor.java b/aai-traversal/src/main/java/org/openecomp/aai/interceptors/AAILogJAXRSInInterceptor.java
new file mode 100644 (file)
index 0000000..80127d0
--- /dev/null
@@ -0,0 +1,283 @@
+/*-
+ * ============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.interceptors;
+
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.core.MediaType;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.LoggingMessage;
+import org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor;
+import org.apache.cxf.message.Message;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.rest.util.EchoResponse;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import org.openecomp.aai.util.HbaseSaltPrefixer;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class AAILogJAXRSInInterceptor extends JAXRSInInterceptor {
+
+       protected final String COMPONENT = "aairest";
+       protected final String CAMEL_REQUEST ="CamelHttpUrl";
+       private static final Pattern uuidPattern = Pattern.compile("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$");
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAILogJAXRSInInterceptor.class);
+       
+       /**
+        * {@inheritDoc}
+        */
+       public void handleMessage(Message message) {
+
+               boolean go = false;
+               String uri = null;
+               String query = null;
+               try {
+               
+                       uri = (String)message.get(CAMEL_REQUEST);
+                       if (uri != null) { 
+                               query = (String)message.get(Message.QUERY_STRING);
+                       }
+                       
+                       if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_INTERCEPTOR).equalsIgnoreCase("true") &&
+                                       AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_ENABLED).equalsIgnoreCase("true")) {
+                               go = true;
+                               message.getExchange().put("AAI_LOGGING_HBASE_ENABLED", 1);
+                               if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_LOGREQUEST).equalsIgnoreCase("true") ) {
+                                       message.getExchange().put("AAI_LOGGING_HBASE_LOGREQUEST", 1);
+                               }
+                               if (AAIConfig.get(AAIConstants.AAI_LOGGING_HBASE_LOGRESPONSE).equalsIgnoreCase("true") ) {
+                                       message.getExchange().put("AAI_LOGGING_HBASE_LOGRESPONSE", 1);
+                               }
+                       }
+                       if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_ENABLED).equalsIgnoreCase("true") ) {
+                               go = true;
+                               message.getExchange().put("AAI_LOGGING_TRACE_ENABLED", 1);
+                               if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_LOGREQUEST).equalsIgnoreCase("true") ) {
+                                       message.getExchange().put("AAI_LOGGING_TRACE_LOGREQUEST", 1);
+                               }
+                               if (AAIConfig.get(AAIConstants.AAI_LOGGING_TRACE_LOGRESPONSE).equalsIgnoreCase("true") ) {
+                                       message.getExchange().put("AAI_LOGGING_TRACE_LOGRESPONSE", 1);
+                               }
+                       }
+               } catch (AAIException e1) {
+                       ErrorLogHelper.logException(e1);
+               }
+               
+               if (uri.contains(EchoResponse.echoPath)) {
+                       // if it's a health check, we don't want to log ANYTHING if it's a lightweight one
+                       if (query == null) {
+                               if (message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED")) {
+                                       message.getExchange().remove("AAI_LOGGING_HBASE_ENABLED");
+                               }
+                               if (message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) { 
+                                       message.getExchange().remove("AAI_LOGGING_TRACE_ENABLED");
+                               }
+                               go = false;
+                       }
+               }
+               else if (uri.contains("/translog/")) {
+                       // if it's a translog query, we don't want to log the responses
+                       if (message.getExchange().containsKey("AAI_LOGGING_HBASE_LOGRESPONSE")) {
+                               message.getExchange().remove("AAI_LOGGING_HBASE_LOGRESPONSE");
+                       }
+                       if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGRESPONSE")) {
+                               message.getExchange().remove("AAI_LOGGING_TRACE_LOGRESPONSE");
+                       }
+               }
+               
+               if (go == false) { // there's nothing to do 
+                       return;
+               }
+
+               // DONE: get a TXID based on hostname, time (YYYYMMDDHHMMSSMILLIS,  and LoggingMessage.nextId(); 20150326145301-1
+               String now = genDate();
+
+               message.getExchange().put("AAI_RQST_TM", now);
+
+               String id = (String)message.getExchange().get(LoggingMessage.ID_KEY);
+
+               String fullId = null;
+               try {
+                       if (id == null) {
+                               id = LoggingMessage.nextId();
+                       }
+                       fullId = AAIConfig.get(AAIConstants.AAI_NODENAME) + "-" + now + "-" + id;
+                       fullId = HbaseSaltPrefixer.getInstance().prependSalt(fullId);
+                       message.getExchange().put(LoggingMessage.ID_KEY, fullId);
+               } catch (AAIException e1) {
+                       LOGGER.debug("config problem", e1);
+               }
+               
+               if (fullId == null) { 
+                       fullId = now + "-" + id;
+                       fullId = HbaseSaltPrefixer.getInstance().prependSalt(fullId);
+               }
+               message.put(LoggingMessage.ID_KEY, fullId);
+               final LoggingMessage buffer = new LoggingMessage("Message", fullId);
+
+               Integer responseCode = (Integer)message.get(Message.RESPONSE_CODE);
+               if (responseCode != null) {
+                       buffer.getResponseCode().append(responseCode);
+               }
+
+               String encoding = (String)message.get(Message.ENCODING);
+
+               if (encoding != null) {
+                       buffer.getEncoding().append(encoding);
+               }
+               String httpMethod = (String)message.get(Message.HTTP_REQUEST_METHOD);
+               if (httpMethod != null) {
+                       buffer.getHttpMethod().append(httpMethod);
+               }
+
+               String ct = (String)message.get(Message.CONTENT_TYPE);
+               if (ct != null) {
+                       if ("*/*".equals(ct)) {
+                               message.put(Message.CONTENT_TYPE, MediaType.APPLICATION_JSON);
+                               ct = MediaType.APPLICATION_JSON;
+                       }
+                       buffer.getContentType().append(ct);
+
+               }
+               Object headers = message.get(Message.PROTOCOL_HEADERS);
+               if (headers != null) {
+                       buffer.getHeader().append(headers);
+                       
+                       Map<String, List<String>> headersList = CastUtils.cast((Map<?, ?>)message.get(Message.PROTOCOL_HEADERS));
+                       String transId = "";
+                       List<String> xt = headersList.get("X-TransactionId");
+                       String newTransId = transId;
+                       boolean missingTransId = false;
+                       boolean replacedTransId = false;
+                       String logMsg = null;
+                       if (xt != null) {
+                               for (String transIdValue : xt) {
+                                       transId = transIdValue;
+                               }       
+                               Matcher matcher = uuidPattern.matcher(transId);
+                               if (!matcher.find()) {
+                                       replacedTransId = true;
+                                       // check if there's a colon, and check the first group?
+                                       if (transId.contains(":")) {
+                                               String[] uuidParts = transId.split(":");
+                                               Matcher matcher2 = uuidPattern.matcher(uuidParts[0]);
+                                               if (matcher2.find()) { 
+                                                       newTransId = uuidParts[0];
+                                               } else {
+                                                       // punt, we tried to find it, it has a colon but no UUID-1
+                                                       newTransId = UUID.randomUUID().toString();
+                                               }
+                                       } else {
+                                               newTransId = UUID.randomUUID().toString();
+                                       }
+                               }
+                       } else { 
+                               newTransId = UUID.randomUUID().toString();
+                               missingTransId = true;
+                       }
+                                               
+                       if (missingTransId || replacedTransId) {
+                               List<String> txList = new ArrayList<String>();
+                               txList.add(newTransId);
+                               headersList.put("X-TransactionId", txList);
+                               if (missingTransId) { 
+                                       logMsg = "Missing requestID. Assigned " + newTransId;
+                               } else if (replacedTransId) { 
+                                       logMsg = "Replaced invalid requestID of " + transId + " Assigned " + newTransId;
+                               }
+                       } 
+                       
+                       List<String> contentType = headersList.get("Content-Type");
+                       if (contentType == null) {
+                               ct = (String)message.get(Message.CONTENT_TYPE);
+                               headersList.put(Message.CONTENT_TYPE, Collections.singletonList(ct));
+                       }
+                       
+                       LOGGER.auditEvent("REST " + httpMethod + " " + ((query != null)? uri+"?"+query : uri) + " HbaseTxId=" + fullId);
+                       LOGGER.info(logMsg);
+               }
+
+
+               if (uri != null) {
+                       buffer.getAddress().append(uri);
+                       if (query != null) {
+                               buffer.getAddress().append("?").append(query);
+                       }
+               }
+
+               InputStream is = message.getContent(InputStream.class);
+               if (is != null) {
+                       try {
+                               String currentPayload = IOUtils.toString(is, "UTF-8");
+                               IOUtils.closeQuietly(is);
+                               buffer.getPayload().append(currentPayload);
+                               is = IOUtils.toInputStream(currentPayload, "UTF-8");
+                               message.setContent(InputStream.class, is);
+                               IOUtils.closeQuietly(is);
+                       } catch (Exception e) { 
+                               // It's ok to not have request input content
+                               // throw new Fault(e); 
+                       }
+               }
+
+               // this will be saved in the message exchange, and can be pulled out later...
+               message.getExchange().put(fullId + "_REQUEST", buffer.toString());
+       }
+
+       /**
+        * Gen date.
+        *
+        * @param aaiLogger the aai logger
+        * @param logline the logline
+        * @return the string
+        */
+       protected String genDate() {
+               Date date = new Date();
+               DateFormat formatter = null;
+               try {
+                       formatter = new SimpleDateFormat(AAIConfig.get(AAIConstants.HBASE_TABLE_TIMESTAMP_FORMAT));
+               } catch (AAIException ex) {
+                       ErrorLogHelper.logException(ex);
+               } finally {
+                       if (formatter == null) {
+                               formatter = new SimpleDateFormat("YYMMdd-HH:mm:ss:SSS");
+                       }
+               }
+
+               return formatter.format(date);
+       }
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/interceptors/AAILogJAXRSOutInterceptor.java b/aai-traversal/src/main/java/org/openecomp/aai/interceptors/AAILogJAXRSOutInterceptor.java
new file mode 100644 (file)
index 0000000..0f5e457
--- /dev/null
@@ -0,0 +1,323 @@
+/*-
+ * ============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.interceptors;
+
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.LoggingMessage;
+import org.apache.cxf.io.CacheAndWriteOutputStream;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.io.CachedOutputStreamCallback;
+import org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor;
+import org.apache.cxf.message.Message;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.util.AAIConfig;
+import org.openecomp.aai.util.AAIConstants;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+// right after the request is complete, there may be content
+public class AAILogJAXRSOutInterceptor extends JAXRSOutInterceptor {
+
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAILogJAXRSOutInterceptor.class);
+       
+       protected final String COMPONENT = "aairest";
+       protected final String CAMEL_REQUEST = "CamelHttpUrl";
+
+       /**
+        * {@inheritDoc}
+        */
+       public void handleMessage(Message message) {
+
+               String fullId = (String) message.getExchange().get(LoggingMessage.ID_KEY);
+
+               Map<String, List<String>> headers = CastUtils.cast((Map<?, ?>) message.get(Message.PROTOCOL_HEADERS));
+               if (headers == null) {
+                       headers = new HashMap<String, List<String>>();
+               }
+
+               headers.put("X-AAI-TXID", Collections.singletonList(fullId));
+               message.put(Message.PROTOCOL_HEADERS, headers);
+
+               Message outMessage = message.getExchange().getOutMessage();
+               final OutputStream os = outMessage.getContent(OutputStream.class);
+               if (os == null) {
+                       return;
+               }
+
+               // we only want to register the callback if there is good reason for it.
+               if (message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED") || message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) {
+
+                       final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os);
+                       message.setContent(OutputStream.class, newOut);
+                       newOut.registerCallback(new LoggingCallback(message, os));
+               }
+
+       }
+
+       class LoggingCallback implements CachedOutputStreamCallback {
+
+               private final Message message;
+               private final OutputStream origStream;
+
+               public LoggingCallback(final Message msg, final OutputStream os) {
+                       this.message = msg;
+                       this.origStream = os;
+               }
+
+               public void onFlush(CachedOutputStream cos) {
+
+               }
+
+               public void onClose(CachedOutputStream cos) {
+
+                       String getValue = "";
+                       String postValue = "";
+                       String logValue = "";
+
+                       try {
+                               logValue = AAIConfig.get("aai.transaction.logging");
+                               getValue = AAIConfig.get("aai.transaction.logging.get");
+                               postValue = AAIConfig.get("aai.transaction.logging.post");
+                       } catch (AAIException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+
+                       if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED") && !message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) {
+                               return;
+                       }
+
+                       String fullId = (String) message.getExchange().get(LoggingMessage.ID_KEY);
+
+                       Message inMessage = message.getExchange().getInMessage();
+                       String transId = null;
+                       String fromAppId = null;
+
+                       Map<String, List<String>> headersList = CastUtils.cast((Map<?, ?>) inMessage.get(Message.PROTOCOL_HEADERS));
+                       if (headersList != null) {
+                               List<String> xt = headersList.get("X-TransactionId");
+                               if (xt != null) {
+                                       for (String transIdValue : xt) {
+                                               transId = transIdValue;
+                                       }
+                               }
+                               List<String> fa = headersList.get("X-FromAppId");
+                               if (fa != null) {
+                                       for (String fromAppIdValue : fa) {
+
+                                               fromAppId = fromAppIdValue;
+                                       }
+                               }
+                       }
+
+                       String httpMethod = (String) inMessage.get(Message.HTTP_REQUEST_METHOD);
+
+                       String uri = (String) inMessage.get(CAMEL_REQUEST);
+                       String fullUri = uri;
+                       if (uri != null) {
+                               String query = (String) message.get(Message.QUERY_STRING);
+                               if (query != null) {
+                                       fullUri = uri + "?" + query;
+                               }
+                       }
+
+                       String request = (String) message.getExchange().get(fullId + "_REQUEST");
+
+                       Message outMessage = message.getExchange().getOutMessage();
+
+                       final LoggingMessage buffer = new LoggingMessage("OUTMessage", fullId);
+
+                       // should we check this, and make sure it's not an error?
+                       Integer responseCode = (Integer) outMessage.get(Message.RESPONSE_CODE);
+                       if (responseCode == null) {
+                               responseCode = 200; // this should never happen, but just in
+                                                                       // case we don't get one
+                       }
+                       buffer.getResponseCode().append(responseCode);
+
+                       String encoding = (String) outMessage.get(Message.ENCODING);
+
+                       if (encoding != null) {
+                               buffer.getEncoding().append(encoding);
+                       }
+
+                       String ct = (String) outMessage.get(Message.CONTENT_TYPE);
+                       if (ct != null) {
+                               buffer.getContentType().append(ct);
+                       }
+
+                       Object headers = outMessage.get(Message.PROTOCOL_HEADERS);
+                       if (headers != null) {
+                               buffer.getHeader().append(headers);
+                       }
+
+                       Boolean ss = false;
+                       if (responseCode >= 200 && responseCode <= 299) {
+                               ss = true;
+                       }
+                       String response = buffer.toString();
+
+                       // this should have been set by the in interceptor
+                       String rqstTm = (String) message.getExchange().get("AAI_RQST_TM");
+
+                       // just in case it wasn't, we'll put this here. not great, but it'll
+                       // have a val.
+                       if (rqstTm == null) {
+                               rqstTm = genDate();
+                       }
+
+
+                       String respTm = genDate();
+
+                       try {
+                               String actualRequest = request;
+                               StringBuilder builder = new StringBuilder();
+                               cos.writeCacheTo(builder, 100000);
+                               // here comes my xml:
+                               String payload = builder.toString();
+
+                               String actualResponse = response;
+                               if (payload == null) {
+
+                               } else {
+                                       actualResponse = response + payload;
+                               }
+
+                               // we only log to AAI log if it's eanbled in the config props
+                               // file
+                               if (message.getExchange().containsKey("AAI_LOGGING_TRACE_ENABLED")) {
+
+                                       if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGREQUEST")) {
+
+                                               // strip newlines from request
+                                               String traceRequest = actualRequest;
+                                               traceRequest = traceRequest.replace("\n", " ");
+                                               traceRequest = traceRequest.replace("\r", "");
+                                               traceRequest = traceRequest.replace("\t", "");
+                                               LOGGER.debug(traceRequest);
+                                       }
+                                       if (message.getExchange().containsKey("AAI_LOGGING_TRACE_LOGRESPONSE")) {
+                                               // strip newlines from response
+                                               String traceResponse = actualResponse;
+                                               traceResponse = traceResponse.replace("\n", " ");
+                                               traceResponse = traceResponse.replace("\r", "");
+                                               traceResponse = traceResponse.replace("\t", "");
+
+                                               LOGGER.debug(traceResponse);
+                                       }
+                               }
+
+                               // we only log to HBASE if it's enabled in the config props file
+                               // TODO: pretty print XML/JSON. we might need to get the payload
+                               // and envelope seperately
+                               if (message.getExchange().containsKey("AAI_LOGGING_HBASE_ENABLED")) {
+                                       if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_LOGREQUEST")) {
+                                               actualRequest = "loggingDisabled";
+                                       }
+                                       if (!message.getExchange().containsKey("AAI_LOGGING_HBASE_LOGRESPONSE")) {
+                                               actualResponse = "loggingDisabled";
+                                       }
+
+                                       LOGGER.debug("action={}, urlin={}, HbTransId={}", httpMethod, fullUri, fullId);
+
+                                       if (logValue.equals("false")) {
+                                       } else if (getValue.equals("false") && httpMethod.equals("GET")) {
+                                       } else if (postValue.equals("false") && httpMethod.equals("POST")) {
+                                       } else {
+                                               putTransaction(transId, responseCode.toString(), rqstTm, respTm, fromAppId + ":" + transId, fullUri, httpMethod, request, response, actualResponse);
+
+                                       }
+                               }
+                       } catch (Exception ex) {
+                               // ignore
+                       }
+
+                       message.setContent(OutputStream.class, origStream);
+                       
+                       LOGGER.auditEvent("HTTP Response Code: {}", responseCode.toString());
+               }
+
+       }
+
+       protected String genDate() {
+               Date date = new Date();
+               DateFormat formatter = null;
+               try {
+                       formatter = new SimpleDateFormat(AAIConfig.get(AAIConstants.HBASE_TABLE_TIMESTAMP_FORMAT));
+               } catch (AAIException ex) {
+                       ErrorLogHelper.logException(ex);
+               } finally {
+                       if (formatter == null) {
+                               formatter = new SimpleDateFormat("YYMMdd-HH:mm:ss:SSS");
+                       }
+               }
+               return formatter.format(date);
+       }
+
+       public String putTransaction(String tid, String status, String rqstTm, String respTm, String srcId, String rsrcId, String rsrcType, String rqstBuf, String respBuf, String actualResponse) {
+               String tm = null;
+               String fromAppId = srcId.substring(0, srcId.indexOf(':'));
+               String transId = srcId.substring(srcId.indexOf(':') + 1);
+
+               if (tid == null || "".equals(tid)) {
+                       Date date = new Date();
+                       DateFormat formatter = null;
+                       try {
+                               formatter = new SimpleDateFormat(AAIConfig.get(AAIConstants.HBASE_TABLE_TIMESTAMP_FORMAT));
+                       } catch (Exception e) {
+                               formatter = new SimpleDateFormat("YYYYMMdd-HH:mm:ss:SSS");
+                       }
+                       tm = formatter.format(date);    
+                       tid = tm + "-";
+               }
+
+               String htid = tid;
+
+               if (rqstTm == null || "".equals(rqstTm)) {
+                       rqstTm = tm;
+               }
+
+               if (respTm == null || "".equals(respTm)) {
+                       respTm = tm;
+               }
+
+               try {
+                       LOGGER.debug(" transactionId:" + tid + " status: " + status + " rqstDate: " + rqstTm + " respDate: " + respTm + " sourceId: " + srcId + " resourceId: "
+                                       + rsrcId + " resourceType: " + rsrcType + " payload rqstBuf: " + rqstBuf + " payload respBuf: " + respBuf + " Payload Error Messages: " + actualResponse);
+                       return htid;
+               } catch (Exception e) {
+                       ErrorLogHelper.logError("AAI_4000", "Exception updating HBase:");
+                       return htid;
+               }
+
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/interceptors/PostAaiAjscInterceptor.java b/aai-traversal/src/main/java/org/openecomp/aai/interceptors/PostAaiAjscInterceptor.java
new file mode 100644 (file)
index 0000000..3a4f899
--- /dev/null
@@ -0,0 +1,63 @@
+/*-
+ * ============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.interceptors;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.openecomp.aai.logging.LoggingContext;
+import org.openecomp.aai.logging.LoggingContext.StatusCode;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import ajsc.beans.interceptors.AjscInterceptor;
+
+public class PostAaiAjscInterceptor implements AjscInterceptor {
+
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(PostAaiAjscInterceptor.class);
+
+       private static class LazyAaiAjscInterceptor {
+       public static final PostAaiAjscInterceptor INSTANCE = new PostAaiAjscInterceptor();
+       }
+
+    public static PostAaiAjscInterceptor getInstance() {
+       return LazyAaiAjscInterceptor.INSTANCE;
+    }
+
+       @Override
+       public boolean allowOrReject(HttpServletRequest req, HttpServletResponse resp, Map<?, ?> paramMap)
+                       throws Exception {
+               final String responseCode = LoggingContext.responseCode();
+
+               if (responseCode != null && responseCode.startsWith("ERR.")) {
+                       LoggingContext.statusCode(StatusCode.ERROR);
+                       LOGGER.error(req.getRequestURL() + " call failed with responseCode=" + responseCode);
+               } else {
+                       LoggingContext.statusCode(StatusCode.COMPLETE);
+                       LOGGER.info(req.getRequestURL() + " call succeeded");
+               }
+
+               LoggingContext.clear();
+               return true;
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/interceptors/PreAaiAjscInterceptor.java b/aai-traversal/src/main/java/org/openecomp/aai/interceptors/PreAaiAjscInterceptor.java
new file mode 100644 (file)
index 0000000..a2c56d0
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ * ============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.interceptors;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.openecomp.aai.logging.LoggingContext;
+
+import ajsc.beans.interceptors.AjscInterceptor;
+
+public class PreAaiAjscInterceptor implements AjscInterceptor {
+       
+       private static class LazyAaiAjscInterceptor {
+       public static final PreAaiAjscInterceptor INSTANCE = new PreAaiAjscInterceptor();
+       }
+
+    public static PreAaiAjscInterceptor getInstance() {
+       return LazyAaiAjscInterceptor.INSTANCE;
+    }
+     
+       @Override
+       public boolean allowOrReject(HttpServletRequest req, HttpServletResponse resp, Map<?, ?> paramMap)
+                       throws Exception {
+
+               LoggingContext.init();
+
+               LoggingContext.requestId(req.getHeader("X-TransactionId"));
+               LoggingContext.partnerName(req.getHeader("X-FromAppId"));
+               LoggingContext.serviceName(req.getMethod() + " " + req.getRequestURI().toString());
+
+               return true;
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/ExceptionHandler.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/ExceptionHandler.java
new file mode 100644 (file)
index 0000000..f1a6f47
--- /dev/null
@@ -0,0 +1,129 @@
+/*-
+ * ============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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.sun.istack.SAXParseException2;
+
+/**
+ * The Class ExceptionHandler.
+ */
+@Provider
+public class ExceptionHandler implements ExceptionMapper<Exception> {
+
+    @Context
+    private HttpServletRequest request;
+    
+    @Context
+    private HttpHeaders headers;
+    
+    /**
+        * @{inheritDoc}
+        */
+    @Override
+    public Response toResponse(Exception exception) {
+
+       Response response = null;
+       ArrayList<String> templateVars = new ArrayList<String>();
+
+       //the general case is that cxf will give us a WebApplicationException
+       //with a linked exception
+       if (exception instanceof WebApplicationException) { 
+               WebApplicationException e = (WebApplicationException) exception;
+               if (e.getCause() != null) {
+                       if (e.getCause() instanceof SAXParseException2) {
+                               templateVars.add("UnmarshalException");
+                               AAIException ex = new AAIException("AAI_4007", exception);
+                               response = Response
+                                               .status(400)
+                                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+                                               .build();
+                       }
+               }
+       } else if (exception instanceof JsonParseException) {
+               //jackson does it differently so we get the direct JsonParseException
+               templateVars.add("JsonParseException");
+               AAIException ex = new AAIException("AAI_4007", exception);
+               response = Response
+                               .status(400)
+                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+                               .build();
+        } else if (exception instanceof JsonMappingException) {
+               //jackson does it differently so we get the direct JsonParseException
+               templateVars.add("JsonMappingException");
+               AAIException ex = new AAIException("AAI_4007", exception);
+               response = Response
+                               .status(400)
+                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+                               .build();
+        } 
+       
+       // it didn't get set above, we wrap a general fault here
+       if (response == null) { 
+               
+               Exception actual_e = exception;
+               if (exception instanceof WebApplicationException) { 
+                       WebApplicationException e = (WebApplicationException) exception;
+                       response = e.getResponse();
+               } else { 
+                       templateVars.add(request.getMethod());
+                       templateVars.add("unknown");
+                       AAIException ex = new AAIException("AAI_4000", actual_e);
+                       List<MediaType> mediaTypes = headers.getAcceptableMediaTypes();
+                       int setError = 0;
+
+                       for (MediaType mediaType : mediaTypes) { 
+                               if (MediaType.APPLICATION_XML_TYPE.isCompatible(mediaType)) {
+                                       response = Response
+                                                       .status(400)
+                                                       .type(MediaType.APPLICATION_XML_TYPE)
+                                                       .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+                                                       .build();       
+                                       setError = 1;
+                               } 
+                       }
+                       if (setError == 0) { 
+                               response = Response
+                                               .status(400)
+                                               .type(MediaType.APPLICATION_JSON_TYPE)
+                                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+                                               .build();       
+                       }
+               }
+       }               
+       return response;
+    }
+}
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
new file mode 100644 (file)
index 0000000..af1d350
--- /dev/null
@@ -0,0 +1,182 @@
+/*-
+ * ============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;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.Encoded;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+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;
+import org.openecomp.aai.introspection.Version;
+import org.openecomp.aai.parsers.query.QueryParser;
+import org.openecomp.aai.rest.db.HttpEntry;
+import org.openecomp.aai.rest.search.GenericQueryProcessor;
+import org.openecomp.aai.rest.search.QueryProcessorType;
+import org.openecomp.aai.restcore.HttpMethod;
+import org.openecomp.aai.restcore.RESTAPI;
+import org.openecomp.aai.restcore.util.URITools;
+import org.openecomp.aai.serialization.db.DBSerializer;
+import org.openecomp.aai.serialization.engines.QueryStyle;
+import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
+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;
+
+@Path("{version: v9|v1[0]}/query")
+public class QueryConsumer extends RESTAPI {
+       
+       /** The introspector factory type. */
+       private ModelType introspectorFactoryType = ModelType.MOXY;
+       
+       private QueryProcessorType processorType = QueryProcessorType.GREMLIN_SERVER;
+       /** The query style. */
+       private QueryStyle queryStyle = QueryStyle.TRAVERSAL;
+       @PUT
+       @Consumes({ MediaType.APPLICATION_JSON})
+       @Produces({ MediaType.APPLICATION_JSON})
+       public Response executeQuery(String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) {
+               
+               String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
+               String realTime = headers.getRequestHeaders().getFirst("Real-Time");
+               String queryProcessor = headers.getRequestHeaders().getFirst("QueryProcessor");
+               QueryProcessorType processorType = this.processorType;
+               Response response = null;
+               TransactionalGraphEngine dbEngine = null;
+               try {
+
+                       Format format = Format.valueOf(queryFormat);
+                       if (queryProcessor != null) {
+                               processorType = QueryProcessorType.valueOf(queryProcessor);
+                       }
+                       SubGraphStyle subGraphStyle = SubGraphStyle.valueOf(subgraph);
+                       JsonParser parser = new JsonParser();
+                       
+                       JsonObject input = parser.parse(content).getAsJsonObject();
+                       
+                       JsonElement startElement = input.get("start");
+                       JsonElement queryElement = input.get("query");
+                       JsonElement gremlinElement = input.get("gremlin");
+                       List<URI> startURIs = new ArrayList<>();
+                       String queryURI = "";
+                       String gremlin = "";
+                       
+                       Version version = Version.valueOf(versionParam);
+                       DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
+                       HttpEntry httpEntry = new HttpEntry(version, introspectorFactoryType, queryStyle, type);
+                       dbEngine = httpEntry.getDbEngine();
+
+                       if (startElement != null) {
+       
+                               if (startElement.isJsonArray()) {
+                                       for (JsonElement element : startElement.getAsJsonArray()) {
+                                               startURIs.add(new URI(element.getAsString()));
+                                       }
+                               } else {
+                                       startURIs.add(new URI(startElement.getAsString()));
+                               }
+                       }
+                       
+                       if (queryElement != null) {
+                               queryURI = queryElement.getAsString();
+                       }
+                       if (gremlinElement != null) {
+                               gremlin = gremlinElement.getAsString();
+                       }
+                       URI queryURIObj = new URI(queryURI);
+                       GenericQueryProcessor processor = null;
+                       
+                       if (!startURIs.isEmpty()) {
+                               Set<Vertex> vertexSet = new LinkedHashSet<>();
+                               QueryParser uriQuery;
+                               List<Vertex> vertices;
+                               for (URI startUri : startURIs) {
+                                       uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(startUri, URITools.getQueryMap(startUri));
+                                       vertices = uriQuery.getQueryBuilder().toList();
+                                       vertexSet.addAll(vertices);
+                               }
+
+                               processor = new GenericQueryProcessor.Builder(dbEngine)
+                                               .startFrom(vertexSet).queryFrom(queryURIObj)
+                                               .processWith(processorType).create();
+                       } else if (!queryURI.equals("")){
+                               processor =  new GenericQueryProcessor.Builder(dbEngine)
+                                               .queryFrom(queryURIObj)
+                                               .processWith(processorType).create();
+                       } else {
+                               processor =  new GenericQueryProcessor.Builder(dbEngine)
+                                               .queryFrom(gremlin)
+                                               .processWith(processorType).create();
+                       }
+                       String result = "";
+                       List<Object> vertices = processor.execute(subGraphStyle);
+                       DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth);
+                       FormatFactory ff = new FormatFactory(httpEntry.getLoader(), serializer);
+                       
+                       Formatter formater =  ff.get(format);
+               
+                       result = formater.output(vertices).toString();
+
+                       response = Response.status(Status.OK)
+                                       .type(MediaType.APPLICATION_JSON)
+                                       .entity(result).build();
+               
+               } catch (AAIException e) {
+                       response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, e);
+               } catch (Exception e ) {
+                       AAIException ex = new AAIException("AAI_4000", e);
+                       
+                       response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, ex);
+               } finally {
+                       if (dbEngine != null) {
+                               dbEngine.rollback();
+                       }
+               }
+               
+               return response;
+       }
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/db/DBRequest.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/db/DBRequest.java
new file mode 100644 (file)
index 0000000..e7b6858
--- /dev/null
@@ -0,0 +1,251 @@
+/*-
+ * ============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.db;
+
+import java.net.URI;
+import java.util.Optional;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.MarshallerProperties;
+import org.openecomp.aai.parsers.query.QueryParser;
+import org.openecomp.aai.restcore.HttpMethod;
+
+/**
+ * The Class DBRequest.
+ */
+public class DBRequest {
+
+       private final QueryParser parser;
+       
+       private final Introspector introspector;
+       
+       private final HttpHeaders headers;
+       
+       private final String transactionId;
+       
+       private final UriInfo info;
+       
+       private final HttpMethod method;
+       
+       private final URI uri;
+       
+       private final Optional<String> rawRequestContent;
+       
+       private final Optional<MarshallerProperties> marshallerProperties;
+
+       
+       /**
+        * Instantiates a new DB request.
+        *
+        * @param method the method
+        * @param uri the uri
+        * @param parser the parser
+        * @param obj the obj
+        * @param headers the headers
+        * @param info the info
+        * @param transactionId the transaction id
+        */
+       private DBRequest(Builder builder) {
+               this.method = builder.getMethod();
+               this.parser = builder.getParser();
+               this.introspector = builder.getIntrospector();
+               this.headers = builder.getHeaders();
+               this.transactionId = builder.getTransactionId();
+               this.info = builder.getInfo();
+               this.uri = builder.getUri();
+               this.marshallerProperties = builder.getMarshallerProperties();
+               this.rawRequestContent = builder.getRawRequestContent();
+       }
+       
+       /**
+        * Gets the headers.
+        *
+        * @return the headers
+        */
+       public HttpHeaders getHeaders() {
+               return headers;
+       }
+       
+       
+       /**
+        * Gets the transaction id.
+        *
+        * @return the transaction id
+        */
+       public String getTransactionId() {
+               return transactionId;
+       }
+       
+       /**
+        * Gets the info.
+        *
+        * @return the info
+        */
+       public UriInfo getInfo() {
+               return info;
+       }
+       
+       /**
+        * Gets the parser.
+        *
+        * @return the parser
+        */
+       public QueryParser getParser() {
+               return parser;
+       }
+
+       /**
+        * Gets the introspector.
+        *
+        * @return the introspector
+        */
+       public Introspector getIntrospector() {
+               return introspector;
+       }
+
+       /**
+        * Gets the method.
+        *
+        * @return the method
+        */
+       public HttpMethod getMethod() {
+               return method;
+       }
+
+       /**
+        * Gets the uri.
+        *
+        * @return the uri
+        */
+       public URI getUri() {
+               return uri;
+       }
+       
+       /**
+        * Gets the raw content.
+        *
+        * @return the raw content
+        */
+       public Optional<String> getRawRequestContent() {
+               return rawRequestContent;
+       }
+       
+       public Optional<MarshallerProperties> getMarshallerProperties() {
+               return marshallerProperties;
+       }
+
+
+
+       public static class Builder {
+
+               private QueryParser parser = null;
+               
+               private Introspector introspector = null;
+               
+               private HttpHeaders headers = null;
+               
+               private String transactionId = null;
+               
+               private UriInfo info = null;
+               
+               private HttpMethod method = null;
+               
+               private URI uri = null;
+                               
+               private Optional<MarshallerProperties> marshallerProperties = Optional.empty();
+               
+               private Optional<String> rawRequestContent = Optional.empty();
+               /**
+                * Instantiates a new DB request.
+                *
+                * @param method the method
+                * @param uri the uri
+                * @param parser the parser
+                * @param obj the obj
+                * @param headers the headers
+                * @param info the info
+                * @param transactionId the transaction id
+                */
+               public Builder(HttpMethod method, URI uri, QueryParser parser, Introspector obj, HttpHeaders headers, UriInfo info, String transactionId) {
+                       this.method = method;
+                       this.parser = parser;
+                       this.introspector = obj;
+                       this.headers = headers;
+                       this.transactionId = transactionId;
+                       this.info = info;
+                       this.uri = uri;
+                       
+               }
+
+               public QueryParser getParser() {
+                       return parser;
+               }
+
+               public Introspector getIntrospector() {
+                       return introspector;
+               }
+
+               public HttpHeaders getHeaders() {
+                       return headers;
+               }
+
+               public String getTransactionId() {
+                       return transactionId;
+               }
+
+               public UriInfo getInfo() {
+                       return info;
+               }
+
+               public HttpMethod getMethod() {
+                       return method;
+               }
+
+               public URI getUri() {
+                       return uri;
+               }
+               
+               public Builder customMarshaller(MarshallerProperties properties) {
+                       this.marshallerProperties = Optional.of(properties);
+                       return this;
+               }
+               
+               public Builder rawRequestContent(String content) {
+                       this.rawRequestContent = Optional.of(content);
+                       return this;
+               }
+               protected Optional<MarshallerProperties> getMarshallerProperties() {
+                       return marshallerProperties;
+               }
+               protected Optional<String> getRawRequestContent() {
+                       return rawRequestContent;
+               }
+               public DBRequest build() {
+                       
+                       return new DBRequest(this);
+               }
+               
+               
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/db/HttpEntry.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/db/HttpEntry.java
new file mode 100644 (file)
index 0000000..60438de
--- /dev/null
@@ -0,0 +1,672 @@
+/*-
+ * ============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.db;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriBuilder;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.javatuples.Pair;
+
+import org.openecomp.aai.db.props.AAIProperties;
+import org.openecomp.aai.dbmap.DBConnectionType;
+import org.openecomp.aai.domain.responseMessage.AAIResponseMessage;
+import org.openecomp.aai.domain.responseMessage.AAIResponseMessageDatum;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.extensions.AAIExtensionMap;
+import org.openecomp.aai.extensions.ExtensionController;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.LoaderFactory;
+import org.openecomp.aai.introspection.MarshallerProperties;
+import org.openecomp.aai.introspection.ModelInjestor;
+import org.openecomp.aai.introspection.ModelType;
+import org.openecomp.aai.introspection.Version;
+import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.parsers.query.QueryParser;
+import org.openecomp.aai.parsers.uri.URIToExtensionInformation;
+import org.openecomp.aai.rest.ueb.UEBNotification;
+import org.openecomp.aai.restcore.HttpMethod;
+import org.openecomp.aai.schema.enums.ObjectMetadata;
+import org.openecomp.aai.serialization.db.DBSerializer;
+import org.openecomp.aai.serialization.engines.QueryStyle;
+import org.openecomp.aai.serialization.engines.TitanDBEngine;
+import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
+import org.openecomp.aai.serialization.engines.query.QueryEngine;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.jsonpatch.JsonPatchException;
+import com.github.fge.jsonpatch.mergepatch.JsonMergePatch;
+import com.thinkaurelius.titan.core.TitanException;
+import com.thinkaurelius.titan.core.TitanTransaction;
+
+/**
+ * The Class HttpEntry.
+ */
+public class HttpEntry {
+
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(HttpEntry.class);
+
+       private final ModelType introspectorFactoryType;
+       
+       private final QueryStyle queryStyle;
+       
+       private final Version version;
+       
+       private final Loader loader;
+       
+       private final TransactionalGraphEngine dbEngine;
+               
+       private boolean processSingle = true;
+
+       /**
+        * Instantiates a new http entry.
+        *
+        * @param version the version
+        * @param modelType the model type
+        * @param queryStyle the query style
+        * @param llBuilder the ll builder
+        */
+       public HttpEntry(Version version, ModelType modelType, QueryStyle queryStyle, DBConnectionType connectionType) {
+               this.introspectorFactoryType = modelType;
+               this.queryStyle = queryStyle;
+               this.version = version;
+               this.loader = LoaderFactory.createLoaderForVersion(introspectorFactoryType, version);
+               this.dbEngine = new TitanDBEngine(
+                               queryStyle,
+                               connectionType,
+                               loader);
+               //start transaction on creation
+               dbEngine.startTransaction();
+
+       }
+       
+       /**
+        * Gets the introspector factory type.
+        *
+        * @return the introspector factory type
+        */
+       public ModelType getIntrospectorFactoryType() {
+               return introspectorFactoryType;
+       }
+
+       /**
+        * Gets the query style.
+        *
+        * @return the query style
+        */
+       public QueryStyle getQueryStyle() {
+               return queryStyle;
+       }
+
+       /**
+        * Gets the version.
+        *
+        * @return the version
+        */
+       public Version getVersion() {
+               return version;
+       }
+
+       /**
+        * Gets the loader.
+        *
+        * @return the loader
+        */
+       public Loader getLoader() {
+               return loader;
+       }
+
+       /**
+        * Gets the db engine.
+        *
+        * @return the db engine
+        */
+       public TransactionalGraphEngine getDbEngine() {
+               return dbEngine;
+       }
+
+       public Pair<Boolean, List<Pair<URI, Response>>> process (List<DBRequest> requests, String sourceOfTruth) throws AAIException {
+               return this.process(requests, sourceOfTruth, true);
+       }
+       /**
+        * Process.
+        * @param requests the requests
+        * @param sourceOfTruth the source of truth
+        *
+        * @return the pair
+        * @throws AAIException the AAI exception
+        */
+       public Pair<Boolean, List<Pair<URI, Response>>> process (List<DBRequest> requests, String sourceOfTruth, boolean enableResourceVersion) throws AAIException {
+               DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth);
+               Response response = null;
+               Status status = Status.NOT_FOUND;
+               Introspector obj = null;
+               QueryParser query = null;
+               URI uri = null;
+               String transactionId = null;
+               UEBNotification notification = new UEBNotification(loader);
+               int depth = AAIProperties.MAXIMUM_DEPTH;
+               List<Pair<URI,Response>> responses = new ArrayList<>();
+               MultivaluedMap<String, String> params = null;
+               HttpMethod method = null;
+               String uriTemp = "";
+               Boolean success = true;
+               QueryEngine queryEngine = dbEngine.getQueryEngine();
+               int maxRetries = 10;
+               int retry = 0;
+               for (DBRequest request : requests) {
+                       try {
+                               for (retry = 0; retry < maxRetries; ++retry) {
+                                       try {
+                                               method = request.getMethod();
+                                               obj = request.getIntrospector();
+                                               query = request.getParser();
+                                               transactionId = request.getTransactionId();
+                                               uriTemp = request.getUri().getRawPath().replaceFirst("^v\\d+/", "");
+                                               uri = UriBuilder.fromPath(uriTemp).build();
+                                               List<Vertex> vertices = query.getQueryBuilder().toList();
+                                               boolean isNewVertex = false;
+                                               String outputMediaType = getMediaType(request.getHeaders().getAcceptableMediaTypes());
+                                               String result = null;
+                                               params = request.getInfo().getQueryParameters(false);
+                                               depth = setDepth(obj, params.getFirst("depth"));
+                                               String cleanUp = params.getFirst("cleanup");
+                                               String requestContext = "";
+                                               List<String> requestContextList = request.getHeaders().getRequestHeader("aai-request-context");
+                                               if (requestContextList != null) {
+                                                       requestContext = requestContextList.get(0);
+                                               }
+                                       
+                                               if (cleanUp == null) {
+                                                       cleanUp = "false";
+                                               }
+                                               if (vertices.size() > 1 && processSingle && !method.equals(HttpMethod.GET)) {
+                                                       if (method.equals(HttpMethod.DELETE)) {
+                                                               throw new AAIException("AAI_6138");
+                                                       } else {
+                                                               throw new AAIException("AAI_6137");
+                                                       }
+                                               }
+                                               if (method.equals(HttpMethod.PUT)) {
+                                                       String resourceVersion = (String)obj.getValue("resource-version");
+                                                       if (vertices.size() == 1) {
+                                                               if (enableResourceVersion) {
+                                                                       serializer.verifyResourceVersion("update", query.getResultType(), (String)vertices.get(0).<String>property("resource-version").orElse(null), resourceVersion, obj.getURI());
+                                                               }
+                                                               isNewVertex = false;
+                                                       } else {
+                                                               if (enableResourceVersion) {
+                                                                       serializer.verifyResourceVersion("create", query.getResultType(), "", resourceVersion, obj.getURI());
+                                                               }
+                                                               isNewVertex = true;
+                                                       }
+                                               } else {
+                                                       if (vertices.size() == 0) {
+                                                               String msg = createNotFoundMessage(query.getResultType(), request.getUri());
+                                                               throw new AAIException("AAI_6114", msg);
+                                                       } else {
+                                                               isNewVertex = false;
+                                                       }
+                                               }
+                                               Vertex v = null;
+                                               if (!isNewVertex) {
+                                                       v = vertices.get(0);
+                                               }
+                                               HashMap<String, Introspector> relatedObjects = new HashMap<>();
+                                               switch (method) {
+                                                       case GET:
+                                                               String nodeOnly = params.getFirst("nodes-only");
+                                                               boolean isNodeOnly = nodeOnly != null;
+                                                               
+                                                               obj = this.getObjectFromDb(vertices, serializer, query, obj, request.getUri(), depth, isNodeOnly, cleanUp);
+                                                               if (obj != null) {
+                                                                       status = Status.OK;
+                                                                       MarshallerProperties properties;
+                                                                       if (!request.getMarshallerProperties().isPresent()) {
+                                                                               properties = 
+                                                                                               new MarshallerProperties.Builder(org.openecomp.aai.restcore.MediaType.getEnum(outputMediaType)).build();
+                                                                       } else {
+                                                                               properties = request.getMarshallerProperties().get();
+                                                                       }
+                                                                       result = obj.marshal(properties);
+                                                               }
+                                                               
+                                                               break;
+                                                       case PUT: 
+                                                               response = this.invokeExtension(dbEngine, this.dbEngine.tx(), method, request, sourceOfTruth, version, loader, obj, uri, true);
+                                                               if (isNewVertex) {
+                                                                       v = serializer.createNewVertex(obj);
+                                                               } else {
+                                                                       serializer.touchStandardVertexProperties(v, false);
+                                                               }
+                                                               serializer.serializeToDb(obj, v, query, uri.getRawPath(), requestContext);
+                                                               this.invokeExtension(dbEngine, this.dbEngine.tx(), HttpMethod.PUT, request, sourceOfTruth, version, loader, obj, uri, false);
+                                                               status = Status.OK;
+                                                               if (isNewVertex) {
+                                                                       status = Status.CREATED;
+                                                               }
+                                                               obj = serializer.getLatestVersionView(v);
+                                                               if (query.isDependent()) {
+                                                                       relatedObjects = this.getRelatedObjects(serializer, queryEngine, v);
+                                                               }
+                                                               notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri, obj, relatedObjects);
+                                                               
+                                                               break;
+                                                       case PUT_EDGE:
+                                                               serializer.touchStandardVertexProperties(v, false);
+                                                               serializer.createEdge(obj, v);
+                                                               status = Status.OK;
+                                                               break;
+                                                       case MERGE_PATCH:
+                                                               Introspector existingObj = (Introspector) obj.clone();
+                                                               existingObj = this.getObjectFromDb(vertices, serializer, query, existingObj, request.getUri(), 0, false, cleanUp);
+                                                               String existingJson = existingObj.marshal(false);
+                                                               String newJson;
+                                                               
+                                                               if (request.getRawRequestContent().isPresent()) {
+                                                                       newJson = request.getRawRequestContent().get();
+                                                               } else {
+                                                                       newJson = "";
+                                                               }
+                                                               Object relationshipList = request.getIntrospector().getValue("relationship-list");
+                                                               ObjectMapper mapper = new ObjectMapper();
+                                                               try {
+                                                                       JsonNode existingNode = mapper.readTree(existingJson);
+                                                                       JsonNode newNode = mapper.readTree(newJson);
+                                                                       JsonMergePatch patch = JsonMergePatch.fromJson(newNode);
+                                                                       JsonNode completed = patch.apply(existingNode);
+                                                                       String patched = mapper.writeValueAsString(completed);
+                                                                       Introspector patchedObj = loader.unmarshal(existingObj.getName(), patched);
+                                                                       if (relationshipList == null) {
+                                                                               //if the caller didn't touch the relationship-list, we shouldn't either
+                                                                               patchedObj.setValue("relationship-list", null);
+                                                                       }
+                                                                       serializer.touchStandardVertexProperties(v, false);
+                                                                       serializer.serializeToDb(patchedObj, v, query, uri.getRawPath(), requestContext);
+                                                                       status = Status.OK;
+                                                                       patchedObj = serializer.getLatestVersionView(v);
+                                                                       if (query.isDependent()) {
+                                                                               relatedObjects = this.getRelatedObjects(serializer, queryEngine, v);
+                                                                       }
+                                                                       notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri, patchedObj, relatedObjects);
+                                                               } catch (IOException | JsonPatchException e) {
+                                                                       throw new AAIException("AAI_3000", "could not perform patch operation");
+                                                               }
+                                                               break;
+                                                       case DELETE:
+                                                               String resourceVersion = params.getFirst("resource-version");
+                                                               obj = serializer.getLatestVersionView(v);
+                                                               if (query.isDependent()) {
+                                                                       relatedObjects = this.getRelatedObjects(serializer, queryEngine, v);
+                                                               }
+                                                               this.invokeExtension(dbEngine, this.dbEngine.tx(), method, request, sourceOfTruth, version, loader, obj, uri, true);
+                                                               serializer.delete(v, resourceVersion, enableResourceVersion);
+                                                               this.invokeExtension(dbEngine, this.dbEngine.tx(), method, request, sourceOfTruth, version, loader, obj, uri, false);
+                                                               status = Status.NO_CONTENT;
+                                                               notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri, obj, relatedObjects);
+                                                               break;
+                                                       case DELETE_EDGE:
+                                                               serializer.touchStandardVertexProperties(v, false);
+                                                               serializer.deleteEdge(obj, v);
+                                                               status = Status.NO_CONTENT;
+                                                               break;
+                                                       default:
+                                                               break;
+                                               }
+                                               
+                                               
+                                               /* temporarily adding vertex id to the headers
+                                                * to be able to use for testing the vertex id endpoint functionality
+                                                * since we presently have no other way of generating those id urls
+                                               */
+                                               if (response == null && v != null && (
+                                                       method.equals(HttpMethod.PUT)
+                                                       || method.equals(HttpMethod.GET)
+                                                       || method.equals(HttpMethod.MERGE_PATCH))
+                                               ) {
+                                                       String myvertid = v.id().toString();
+                                                       response = Response.status(status)
+                                                                       .header("vertex-id", myvertid)
+                                                                       .entity(result)
+                                                                       .type(outputMediaType).build();
+                                               } else if (response == null) {
+                                                       response = Response.status(status)
+                                                                       .type(outputMediaType).build();
+                                               } else {
+                                                       //response already set to something
+                                               }
+                                               Pair<URI,Response> pairedResp = Pair.with(request.getUri(), response);
+                                               responses.add(pairedResp);
+                                               //break out of retry loop
+                                               break;
+                                       } catch (TitanException e) {
+                                               this.dbEngine.rollback();
+                                               AAIException ex = new AAIException("AAI_6142", e);
+                                               ErrorLogHelper.logException(ex);
+                                               Thread.sleep((retry + 1) * 20);
+                                               this.dbEngine.startTransaction();
+                                               queryEngine = dbEngine.getQueryEngine();
+                                               serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth);
+                                       }
+                               
+                                       if (retry == maxRetries) {
+                                               throw new AAIException("AAI_6134");
+                                       }
+                               }
+                       } catch (AAIException e) {
+                               success = false;
+                               ArrayList<String> templateVars = new ArrayList<String>();
+                               templateVars.add(request.getMethod().toString()); //GET, PUT, etc
+                               templateVars.add(request.getUri().getPath().toString());
+                               templateVars.addAll(e.getTemplateVars());
+                               
+                               response = Response
+                                               .status(e.getErrorObject().getHTTPResponseCode())
+                                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(request.getHeaders().getAcceptableMediaTypes(), e, templateVars))
+                                               .build();
+                               Pair<URI,Response> pairedResp = Pair.with(request.getUri(), response);
+                               responses.add(pairedResp);
+                               continue;
+                       } catch (Exception e) {
+                               success = false;
+                               e.printStackTrace();
+                               AAIException ex = new AAIException("AAI_4000", e);
+                               ArrayList<String> templateVars = new ArrayList<String>();
+                               templateVars.add(request.getMethod().toString()); //GET, PUT, etc
+                               templateVars.add(request.getUri().getPath().toString());
+
+                               response = Response
+                                               .status(ex.getErrorObject().getHTTPResponseCode())
+                                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(request.getHeaders().getAcceptableMediaTypes(), ex, templateVars))
+                                               .build();
+                               Pair<URI, Response> pairedResp = Pair.with(request.getUri(), response);
+                               responses.add(pairedResp);
+                               continue;
+                       }
+               }
+               
+               notification.triggerEvents();
+               Pair<Boolean, List<Pair<URI, Response>>> tuple = Pair.with(success, responses);
+               return tuple;
+       }
+
+       /**
+        * Gets the media type.
+        *
+        * @param mediaTypeList the media type list
+        * @return the media type
+        */
+       private String getMediaType(List <MediaType> mediaTypeList) {
+               String mediaType = MediaType.APPLICATION_JSON;  // json is the default    
+               for (MediaType mt : mediaTypeList) {
+                       if (MediaType.APPLICATION_XML_TYPE.isCompatible(mt)) {
+                               mediaType = MediaType.APPLICATION_XML;
+                       } 
+               }
+               return mediaType;
+       }
+       
+       /**
+        * Gets the object from db.
+        *
+        * @param serializer the serializer
+        * @param g the g
+        * @param query the query
+        * @param obj the obj
+        * @param uri the uri
+        * @param depth the depth
+        * @param cleanUp the clean up
+        * @return the object from db
+        * @throws AAIException the AAI exception
+        * @throws IllegalAccessException the illegal access exception
+        * @throws IllegalArgumentException the illegal argument exception
+        * @throws InvocationTargetException the invocation target exception
+        * @throws SecurityException the security exception
+        * @throws InstantiationException the instantiation exception
+        * @throws NoSuchMethodException the no such method exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        * @throws MalformedURLException the malformed URL exception
+        * @throws AAIUnknownObjectException 
+        * @throws URISyntaxException 
+        */
+       private Introspector getObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query, Introspector obj, URI uri, int depth, boolean nodeOnly, String cleanUp) throws AAIException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, InstantiationException, NoSuchMethodException, UnsupportedEncodingException, AAIUnknownObjectException, URISyntaxException {
+        
+        //nothing found
+        if (results.size() == 0) {
+               String msg = createNotFoundMessage(query.getResultType(), uri);
+                       throw new AAIException("AAI_6114", msg);
+        }
+
+        obj = serializer.dbToObject(results, obj, depth, nodeOnly, cleanUp);
+        
+        return obj;
+       }
+       
+       /**
+        * Invoke extension.
+        *
+        * @param dbEngine the db engine
+        * @param g the g
+        * @param httpMethod the http method
+        * @param transId the trans id
+        * @param fromAppId the from app id
+        * @param apiVersion the api version
+        * @param loader the loader
+        * @param obj the obj
+        * @param uri the uri
+        * @param headers the headers
+        * @param isPreprocess the is preprocess
+        * @return the response
+        * @throws IllegalArgumentException the illegal argument exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        * @throws AAIException the AAI exception
+        */
+       private Response invokeExtension(TransactionalGraphEngine dbEngine, TitanTransaction g, HttpMethod httpMethod, DBRequest request, String fromAppId, Version apiVersion, Loader loader, Introspector obj, URI uri, boolean isPreprocess) throws IllegalArgumentException, UnsupportedEncodingException, AAIException {
+               AAIExtensionMap aaiExtMap = new AAIExtensionMap();
+               ModelInjestor injestor = ModelInjestor.getInstance();
+               Response response = null;
+               URIToExtensionInformation extensionInformation = new URIToExtensionInformation(loader, uri);
+               aaiExtMap.setHttpEntry(this);
+               aaiExtMap.setDbRequest(request);
+               aaiExtMap.setTransId(request.getTransactionId());
+               aaiExtMap.setFromAppId(fromAppId);
+               aaiExtMap.setGraph(g);
+               aaiExtMap.setApiVersion(apiVersion.toString());
+               aaiExtMap.setObjectFromRequest(obj);
+               aaiExtMap.setObjectFromRequestType(obj.getJavaClassName());
+               aaiExtMap.setObjectFromResponse(obj);
+               aaiExtMap.setObjectFromResponseType(obj.getJavaClassName());
+               aaiExtMap.setJaxbContext(injestor.getContextForVersion(apiVersion));
+               aaiExtMap.setUri(uri.getRawPath());
+               aaiExtMap.setTransactionalGraphEngine(dbEngine);
+               aaiExtMap.setLoader(loader);
+               aaiExtMap.setNamespace(extensionInformation.getNamespace());
+               
+               ExtensionController ext = new ExtensionController();
+               ext.runExtension(aaiExtMap.getApiVersion(),
+                               extensionInformation.getNamespace(),
+                               extensionInformation.getTopObject(),
+                               extensionInformation.getMethodName(httpMethod, isPreprocess),
+                               aaiExtMap,
+                               isPreprocess);
+               
+               if (aaiExtMap.getPrecheckAddedList().size() > 0) {
+                       response = notifyOnSkeletonCreation(aaiExtMap, obj, request.getHeaders());
+               }
+               
+               return response;
+       }
+       
+       /**
+        * Notify on skeleton creation.
+        *
+        * @param aaiExtMap the aai ext map
+        * @param input the input
+        * @param headers the headers
+        * @return the response
+        */
+       //Legacy support
+       private Response notifyOnSkeletonCreation(AAIExtensionMap aaiExtMap, Introspector input, HttpHeaders headers) {
+               Response response = null;
+               HashMap<AAIException, ArrayList<String>> exceptionList = new HashMap<AAIException, ArrayList<String>>();
+
+               String keyString = "";
+
+               Set<String> resourceKeys = input.getKeys();
+               for (String key : resourceKeys) { 
+                       keyString += key + "=" + input.getValue(key) + " ";
+               }
+
+               for (AAIResponseMessage msg : aaiExtMap.getPrecheckResponseMessages().getAAIResponseMessage()) {
+                       ArrayList<String> templateVars = new ArrayList<String>();
+
+                       templateVars.add("PUT " + input.getDbName());
+                       templateVars.add(keyString);
+                       List<String> keys = new ArrayList<String>();
+                       templateVars.add(msg.getAaiResponseMessageResourceType());
+                       for (AAIResponseMessageDatum dat : msg.getAaiResponseMessageData().getAAIResponseMessageDatum()) {
+                               keys.add(dat.getAaiResponseMessageDatumKey() + "=" + dat.getAaiResponseMessageDatumValue());
+                       }
+                       templateVars.add(StringUtils.join(keys, ", "));
+                       exceptionList.put(new AAIException("AAI_0004", msg.getAaiResponseMessageResourceType()),
+                                       templateVars);
+               }
+               response = Response
+                               .status(Status.ACCEPTED).entity(ErrorLogHelper
+                                               .getRESTAPIInfoResponse(headers.getAcceptableMediaTypes(), exceptionList))
+                                               .build();
+               
+               return response;
+       }
+       
+       /**
+        * Creates the not found message.
+        *
+        * @param resultType the result type
+        * @param uri the uri
+        * @return the string
+        */
+       private String createNotFoundMessage(String resultType, URI uri) {
+               
+       String msg = "No Node of type " + resultType + " found at: " + uri.getPath();
+
+       return msg;
+       }
+       
+       /**
+        * Sets the depth.
+        *
+        * @param depthParam the depth param
+        * @return the int
+        * @throws AAIException the AAI exception
+        */
+       protected int setDepth(Introspector obj, String depthParam) throws AAIException {
+                       int depth = AAIProperties.MAXIMUM_DEPTH;
+
+        if(depthParam == null){
+                       if(this.version.compareTo(Version.v9) >= 0){
+                               depth = 0;
+                       } else {
+                depth = AAIProperties.MAXIMUM_DEPTH;
+                       }
+               } else {
+                       if (depthParam.length() > 0 && !depthParam.equals("all")){
+                               try {
+                                       depth = Integer.valueOf(depthParam);
+                               } catch (Exception e) {
+                                       throw new AAIException("AAI_4016");
+                               }
+
+                       }
+               }
+        String maxDepth = obj.getMetadata(ObjectMetadata.MAXIMUM_DEPTH);
+        
+               int maximumDepth = AAIProperties.MAXIMUM_DEPTH;
+
+               if(maxDepth != null){
+            try {
+                maximumDepth = Integer.parseInt(maxDepth);
+            } catch(Exception ex){
+                throw new AAIException("AAI_4018");
+            }
+               }
+
+               if(depth > maximumDepth){
+                       throw new AAIException("AAI_3303");
+               }
+
+               return depth;
+       }
+       
+       /**
+        * Checks if is modification method.
+        *
+        * @param method the method
+        * @return true, if is modification method
+        */
+       private boolean isModificationMethod(HttpMethod method) {
+               boolean result = false;
+               
+               if (method.equals(HttpMethod.PUT) || method.equals(HttpMethod.PUT_EDGE) || method.equals(HttpMethod.DELETE_EDGE) || method.equals(HttpMethod.MERGE_PATCH)) {
+                       result = true;
+               }
+               
+               return result;
+               
+       }
+       
+       private HashMap<String, Introspector> getRelatedObjects(DBSerializer serializer, QueryEngine queryEngine, Vertex v) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, InstantiationException, NoSuchMethodException, UnsupportedEncodingException, AAIException, URISyntaxException {
+               HashMap<String, Introspector> relatedVertices = new HashMap<>();
+               List<Vertex> vertexChain = queryEngine.findParents(v);
+               for (Vertex vertex : vertexChain) {
+                       try {
+                               final Introspector vertexObj = serializer.getVertexProperties(vertex);
+                               relatedVertices.put(vertexObj.getObjectId(), vertexObj);
+                       } catch (AAIUnknownObjectException e) {
+                               LOGGER.warn("Unable to get vertex properties, partial list of related vertices returned");
+                       }
+                       
+               }
+               
+               return relatedVertices;
+       }
+       
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/retired/RetiredConsumer.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/retired/RetiredConsumer.java
new file mode 100644 (file)
index 0000000..99974ef
--- /dev/null
@@ -0,0 +1,143 @@
+/*-
+ * ============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.retired;
+
+import java.util.ArrayList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.cxf.jaxrs.ext.PATCH;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.restcore.RESTAPI;
+import org.openecomp.aai.util.AAIConfig;
+
+/**
+ * The Class RetiredConsumer.
+ */
+public abstract class RetiredConsumer extends RESTAPI {
+
+       /**
+        * Creates the message get.
+        *
+        * @param versionParam the version param
+        * @param headers the headers
+        * @param info the info
+        * @param req the req
+        * @return the response
+        */
+       @GET
+       @Path("/{uri:.*}")
+       public Response createMessageGet(@PathParam("version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) {
+               return createMessage(versionParam, headers, info, req);
+       }
+       
+       /**
+        * Creates the message delete.
+        *
+        * @param versionParam the version param
+        * @param headers the headers
+        * @param info the info
+        * @param req the req
+        * @return the response
+        */
+       @DELETE
+       @Path("/{uri:.*}")
+       public Response createMessageDelete(@PathParam("version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) {
+               return createMessage(versionParam, headers, info, req);
+       }
+       
+       /**
+        * Creates the message post.
+        *
+        * @param versionParam the version param
+        * @param headers the headers
+        * @param info the info
+        * @param req the req
+        * @return the response
+        */
+       @POST
+       @Path("/{uri:.*}")
+       public Response createMessagePost(@PathParam("version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) {
+               return createMessage(versionParam, headers, info, req);
+       }
+       
+       @PATCH
+       @Path("/{uri:.*}")
+       public Response createMessagePatch(@PathParam("version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) {
+               return createMessage(versionParam, headers, info, req);
+       }
+       /**
+        * Creates the message put.
+        *
+        * @param versionParam the version param
+        * @param headers the headers
+        * @param info the info
+        * @param req the req
+        * @return the response
+        */
+       @PUT
+       @Path("/{uri:.*}")
+       public Response createMessagePut(@PathParam("version")String versionParam, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) {
+               return createMessage(versionParam, headers, info, req);
+       }
+       
+       
+       /**
+        * Creates the message.
+        *
+        * @param versionParam the version param
+        * @param headers the headers
+        * @param info the info
+        * @param req the req
+        * @return the response
+        */
+       private Response createMessage(String versionParam, HttpHeaders headers, UriInfo info, HttpServletRequest req) {
+               AAIException e = new AAIException("AAI_3007");
+               
+               ArrayList<String> templateVars = new ArrayList<String>();
+
+               if (templateVars.size() == 0) {
+                       templateVars.add("PUT");
+                       templateVars.add(info.getPath().toString());
+                       templateVars.add(versionParam);
+                       templateVars.add(AAIConfig.get("aai.default.api.version", ""));
+               }
+                               
+               Response response = Response
+                               .status(e.getErrorObject().getHTTPResponseCode())
+                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, 
+                                               templateVars)).build(); 
+               
+               return response;
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/retired/V3ThroughV7Consumer.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/retired/V3ThroughV7Consumer.java
new file mode 100644 (file)
index 0000000..55d9482
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============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.retired;
+
+import javax.ws.rs.Path;
+
+@Path("{version: v[3-7]}") 
+public class V3ThroughV7Consumer extends RetiredConsumer {
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/retired/V7V8NamedQueries.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/retired/V7V8NamedQueries.java
new file mode 100644 (file)
index 0000000..3f022a2
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============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.retired;
+
+import javax.ws.rs.Path;
+
+@Path("{version: v[78]}/service-design-and-creation/named-queries")
+public class V7V8NamedQueries extends RetiredConsumer {
+
+}
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
new file mode 100644 (file)
index 0000000..2e9e6a5
--- /dev/null
@@ -0,0 +1,227 @@
+/*-
+ * ============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.io.FileNotFoundException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+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;
+
+import jersey.repackaged.com.google.common.base.Joiner;
+
+public abstract class GenericQueryProcessor {
+
+       protected final Optional<URI> uri;
+       protected final MultivaluedMap<String, String> queryParams;
+       protected final Optional<Collection<Vertex>> vertices;
+       protected static Pattern p = Pattern.compile("query/(.*+)");
+       protected Optional<String> gremlin;
+       protected final TransactionalGraphEngine dbEngine;
+       protected static GremlinServerSingleton gremlinServerSingleton = GremlinServerSingleton.getInstance();
+       protected final boolean isGremlin;
+       
+       protected GenericQueryProcessor(Builder builder) {
+               this.uri = builder.getUri();
+               this.dbEngine = builder.getDbEngine();
+               this.vertices = builder.getVertices();
+               this.gremlin = builder.getGremlin();
+               this.isGremlin = builder.isGremlin();
+               if (uri.isPresent()) {
+                       queryParams = URITools.getQueryMap(uri.get());
+               } else {
+                       queryParams = new MultivaluedHashMap<>();
+               }
+       }
+       
+       protected abstract GraphTraversal<?,?> runQuery(String query, Map<String, Object> params);
+       
+       protected List<Object> processSubGraph(SubGraphStyle style, GraphTraversal<?,?> g) {
+               final List<Object> resultVertices = new Vector<>();
+               g.store("x");
+               
+               if (SubGraphStyle.prune.equals(style) || SubGraphStyle.star.equals(style)) {
+                       g.barrier().bothE();
+                       if (SubGraphStyle.prune.equals(style)) {
+                               g.where(__.otherV().where(P.within("x")));
+                       }
+                       g.dedup().subgraph("subGraph").cap("subGraph").map(x -> (Graph)x.get()).next().traversal().V().forEachRemaining(x -> {
+                               resultVertices.add(x);
+                       });
+               } else {
+                       resultVertices.addAll(g.toList());
+               }
+               return resultVertices;
+       }
+       
+       public List<Object> execute(SubGraphStyle style) throws FileNotFoundException {
+               final List<Object> resultVertices;
+
+               Pair<String, Map<String, Object>> tuple = this.createQuery();
+               String query = tuple.getValue0();
+               Map<String, Object> params = tuple.getValue1();
+
+               if (query.equals("") && (vertices.isPresent() && vertices.get().isEmpty())) {
+                       //nothing to do, just exit
+                       return new ArrayList<>();
+               }
+               GraphTraversal<?,?> g = this.runQuery(query, params);
+               
+               resultVertices = this.processSubGraph(style, g);
+               
+               return resultVertices;
+       }
+       
+       protected Pair<String, Map<String, Object>> createQuery() {
+               Map<String, Object> params = new HashMap<>();
+               String query = "";
+               if (!this.isGremlin) {
+                       Matcher m = p.matcher(uri.get().getPath());
+                       String queryName = "";
+                       if (m.find()) {
+                               queryName = m.group(1);
+                       }
+               
+                       for (String key : queryParams.keySet()) {
+                               params.put(key, queryParams.getFirst(key));
+                       }
+                       
+                       query = gremlinServerSingleton.getStoredQuery(queryName);
+                       if (query == null) {
+                               query = "";
+                       }
+                       
+                       List<Object> ids = new ArrayList<>();
+                       
+                       if (vertices.isPresent() && !vertices.get().isEmpty()) {
+                               for (Vertex v : vertices.get()) {
+                                       ids.add(v.id());
+                               }
+                               StringBuilder sb = new StringBuilder();
+                               sb.append("[");
+                               sb.append(Joiner.on(",").join(ids));
+                               sb.append("]");
+                               String startPrefix = "aaiStartQuery = " + sb.toString() + " as Object[];g.V(aaiStartQuery)";
+                               if (!"".equals(query)) {
+                                       query = startPrefix + "." + query;
+                               } else {
+                                       query = startPrefix;
+                               }
+                       }
+                       
+               } else {
+                       query = gremlin.get();
+               }
+               
+               return new Pair<>(query, params);
+       }
+       
+       public static class Builder {
+
+               private final TransactionalGraphEngine dbEngine;
+               private Optional<URI> uri = Optional.empty();
+               private Optional<String> gremlin = Optional.empty();
+               private boolean isGremlin = false;
+               private Optional<Collection<Vertex>> vertices = Optional.empty();
+               private QueryProcessorType processorType = QueryProcessorType.GREMLIN_SERVER;
+               
+               public Builder(TransactionalGraphEngine dbEngine) {
+                       this.dbEngine = dbEngine;
+               }
+               
+               public Builder queryFrom(URI uri) {
+                       this.uri = Optional.of(uri);
+                       this.isGremlin = false;
+                       return this;
+               }
+               
+               public Builder startFrom(Collection<Vertex> vertices) {
+                       this.vertices = Optional.of(vertices);
+                       return this;
+               }
+               
+               public Builder queryFrom(String gremlin) {
+                       this.gremlin = Optional.of(gremlin);
+                       this.isGremlin = true;
+                       return this;
+               }
+               
+               public Builder processWith(QueryProcessorType type) {
+                       this.processorType = type;
+                       return this;
+               }
+               public TransactionalGraphEngine getDbEngine() {
+                       return dbEngine;
+               }
+
+               public Optional<URI> getUri() {
+                       return uri;
+               }
+
+               public Optional<String> getGremlin() {
+                       return gremlin;
+               }
+
+               public boolean isGremlin() {
+                       return isGremlin;
+               }
+
+               public Optional<Collection<Vertex>> getVertices() {
+                       return vertices;
+               }
+               
+               public QueryProcessorType getProcessorType() {
+                       return processorType;
+               }
+               
+               public GenericQueryProcessor create() {
+                       
+                       if (this.getProcessorType().equals(QueryProcessorType.GREMLIN_SERVER)) {
+                               return new GremlinServerImpl(this);
+                       } else if (this.getProcessorType().equals(QueryProcessorType.LOCAL_GROOVY)) {
+                               return new GroovyShellImpl(this);
+                       } else {
+                               return new GremlinServerImpl(this);
+                       }
+               }
+               
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GremlinGroovyShellSingleton.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GremlinGroovyShellSingleton.java
new file mode 100644 (file)
index 0000000..64159a4
--- /dev/null
@@ -0,0 +1,88 @@
+/*-
+ * ============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.process.traversal.dsl.graph.GraphTraversal;
+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 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 GremlinGroovyShellSingleton {
+
+       private final GroovyShell shell;
+       private GremlinGroovyShellSingleton() {
+               Map<String, Object> 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");
+               CompilerConfiguration config = new CompilerConfiguration();
+               config.addCompilationCustomizers(custom, imports);
+
+               this.shell = new GroovyShell(config);
+       }
+       
+        private static class Helper {
+                private static final GremlinGroovyShellSingleton INSTANCE = new GremlinGroovyShellSingleton();
+        }
+
+        public static GremlinGroovyShellSingleton getInstance() {
+                
+                return Helper.INSTANCE;
+        }
+
+       /** 
+        * @param traversal
+        * @param params
+        * @return result of graph traversal
+        */
+       public GraphTraversal<?, ?> executeTraversal (String traversal, Map<String, Object> params) {
+               Binding binding = new Binding(params);
+               Script script = shell.parse(traversal);
+               script.setBinding(binding);
+               return (GraphTraversal<?, ?>) script.run();
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GremlinServerImpl.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GremlinServerImpl.java
new file mode 100644 (file)
index 0000000..a759b86
--- /dev/null
@@ -0,0 +1,76 @@
+/*-
+ * ============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.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.tinkerpop.gremlin.driver.Client;
+import org.apache.tinkerpop.gremlin.driver.Cluster;
+import org.apache.tinkerpop.gremlin.driver.ResultSet;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+
+import org.openecomp.aai.util.AAIConfig;
+
+public class GremlinServerImpl extends GenericQueryProcessor {
+
+       
+       protected GremlinServerImpl(Builder builder) {
+               super(builder);
+       }
+       
+       
+       @Override
+       protected GraphTraversal<?,?> runQuery(String query, Map<String, Object> params) {
+
+               //must force them into ids because of serialization issue with 
+               //tinkerpop-3.0.1-incubating
+               query += ".id()";
+        String rebindGraph = AAIConfig.get("aai.server.rebind", "g");
+
+        if(!"g".equals(rebindGraph)){
+               query = query.replaceFirst("g\\.V\\(", rebindGraph + ".V(");
+               }
+        
+               Cluster cluster = gremlinServerSingleton.getCluster();
+               Client client = cluster.connect();
+
+               ResultSet results = client.submit(query, params);
+               
+
+               List<Object> vIds = new Vector<>();
+               results.stream().forEach(x -> {
+                       Object obj = x.getObject();
+                       vIds.add(obj);
+               });
+               
+               client.close();
+               
+               if (vIds.isEmpty()) {
+                       return __.start();
+               } else {
+                       return this.dbEngine.asAdmin().getTraversalSource().V(vIds.toArray());
+               }
+       }
+       
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GremlinServerSingleton.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GremlinServerSingleton.java
new file mode 100644 (file)
index 0000000..c54b310
--- /dev/null
@@ -0,0 +1,130 @@
+/*-
+ * ============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 org.openecomp.aai.util.AAIConstants;
+import org.openecomp.aai.util.FileWatcher;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.apache.tinkerpop.gremlin.driver.Cluster;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Date;
+import java.util.Properties;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class GremlinServerSingleton {
+
+    private static EELFLogger logger = EELFManager.getInstance().getLogger(GremlinServerSingleton.class);
+
+    private Cluster cluster;
+    private boolean timerSet;
+    private Timer timer;
+    private Properties properties;
+
+    private static class Helper {
+        private static final GremlinServerSingleton INSTANCE = new GremlinServerSingleton();
+    }
+
+    public static GremlinServerSingleton getInstance() {
+        return Helper.INSTANCE;
+    }
+
+    private GremlinServerSingleton(){
+        init();
+    }
+
+    /**
+     * Initializes the gremlin server singleton
+     * Loads the configuration of the gremlin server and creates a cluster
+     * Loads the gremlin query file into the properties object
+     * Then creates a file watcher to watch the file every ten seconds
+     * and if there is a change in the file, then reloads the file into
+     * the properties object
+     *
+     */
+    private void init() {
+
+        properties = new Properties();
+
+        try {
+            cluster = Cluster.build(new File(AAIConstants.AAI_HOME_ETC_APP_PROPERTIES + "gremlin-server-config.yaml"))
+                    .maxContentLength(6537920)
+                    .create();
+        } catch (FileNotFoundException e) {
+            logger.error("Unable to find the file: " + e);
+        }
+
+        File queryFile = new File(AAIConstants.AAI_HOME_ETC_QUERY);
+
+        try (FileInputStream fis = new FileInputStream(queryFile)){
+            properties.load(fis);
+        } catch (IOException e) {
+            logger.error("Error occurred during the processing of query file: " + e);
+        }
+
+
+        TimerTask task = new FileWatcher(new File(AAIConstants.AAI_HOME_ETC_QUERY)) {
+            @Override
+            protected void onChange(File file) {
+                File queryFile = new File(AAIConstants.AAI_HOME_ETC_QUERY);
+                try (FileInputStream fis = new FileInputStream(queryFile)){
+                    properties.load(fis);
+                    logger.debug("File: " + file + " was changed so the cluster is rebuild for gremlin server");
+                } catch (FileNotFoundException e) {
+                    logger.error("Unable to find the file: " + e);
+                } catch (IOException e) {
+                    logger.error("Error occurred during the processing of query file: " + e);
+                }
+            }
+        };
+
+        if (!timerSet) {
+            timerSet = true;
+            timer = new Timer();
+            timer.schedule( task , new Date(), 10000 );
+        }
+
+    }
+
+    public Cluster getCluster(){
+        return cluster;
+    }
+
+    /**
+     * Gets the key if the properties contains that key
+     *
+     * Purposely not checking if the property exists due
+     * to if you check for the property and then get the property
+     * Then you are going to have to synchronize the method
+     *
+     * @param key the query to check if it exists in the file
+     * @return string if the key exists or null if it doesn't
+     */
+    public String getStoredQuery(String key){
+        return (String) properties.get(key);
+    }
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyShellImpl.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyShellImpl.java
new file mode 100644 (file)
index 0000000..1b64d21
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============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.openecomp.aai.restcore.search.GremlinGroovyShellSingleton;
+
+public class GroovyShellImpl extends GenericQueryProcessor {
+
+       protected GroovyShellImpl(Builder builder) {
+               super(builder);
+       }
+       
+       @Override
+       protected GraphTraversal<?,?> runQuery(String query, Map<String, Object> params) {
+
+               params.put("g", this.dbEngine.asAdmin().getTraversalSource());
+               
+               GremlinGroovyShellSingleton shell = GremlinGroovyShellSingleton.getInstance();
+               
+               return shell.executeTraversal(query, params);
+       }
+               
+}
+
+
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/ModelAndNamedQueryRestProvider.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/ModelAndNamedQueryRestProvider.java
new file mode 100644 (file)
index 0000000..f333dd8
--- /dev/null
@@ -0,0 +1,203 @@
+/*-
+ * ============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.ArrayList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.openecomp.aai.dbgraphmap.SearchGraph;
+import org.openecomp.aai.dbmap.DBConnectionType;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.extensions.AAIExtensionMap;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.restcore.RESTAPI;
+import org.openecomp.aai.util.AAIApiVersion;
+
+/**
+ * Implements the search subdomain in the REST API. All API calls must include
+ * X-FromAppId and X-TransactionId in the header.
+ * 
+ *
+ */
+
+@Path("/search")
+public class ModelAndNamedQueryRestProvider extends RESTAPI {
+       
+       protected static String authPolicyFunctionName = "search";
+       
+       public static final String NAMED_QUERY = "/named-query";
+       
+       public static final String MODEL_QUERY = "/model";
+       
+       /**
+        * Gets the named query response.
+        *
+        * @param headers the headers
+        * @param req the req
+        * @param queryParameters the query parameters
+        * @return the named query response
+        */
+       /* ---------------- Start Named Query --------------------- */
+       @POST
+       @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+       @Path(NAMED_QUERY)
+       public Response getNamedQueryResponse(@Context HttpHeaders headers,
+                                                                               @Context HttpServletRequest req,
+                                                                               String queryParameters) {
+               AAIException ex = null;
+               Response response = null;
+               String fromAppId = null;
+               String transId = null;
+               String rqstTm = genDate();
+               ArrayList<String> templateVars = new ArrayList<String>();       
+               try { 
+                       fromAppId = getFromAppId(headers);
+                       transId = getTransId(headers);
+                       
+                       AAIExtensionMap aaiExtMap = new AAIExtensionMap();                                              
+                       aaiExtMap.setHttpHeaders(headers);
+                       aaiExtMap.setServletRequest(req);
+                       aaiExtMap.setApiVersion(AAIApiVersion.get());
+                       String realTime = headers.getRequestHeaders().getFirst("Real-Time");
+                       //only consider header value for search         
+                       DBConnectionType type = this.determineConnectionType("force-cache", realTime);
+                       
+                       SearchGraph searchGraph = new SearchGraph();
+                       response = searchGraph.runNamedQuery(fromAppId, transId, queryParameters, type, aaiExtMap);
+       
+                       String respTm = genDate();
+                       logTransaction(fromAppId, transId, "GETSDNZONERESPONSE",
+                                       req.getRequestURI(), rqstTm, respTm, "", response);
+
+               } catch (AAIException e) {
+                       // send error response
+                       ex = e;
+                       templateVars.add("POST Search");
+                       templateVars.add("getNamedQueryResponse");
+                       response =  Response
+                                               .status(e.getErrorObject().getHTTPResponseCode())
+                                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
+                                               .build();
+               } catch (Exception e) {
+                       // send error response
+                       ex = new AAIException("AAI_4000", e);
+                       templateVars.add("POST Search");
+                       templateVars.add("getNamedQueryResponse");
+                       response = Response
+                                               .status(Status.INTERNAL_SERVER_ERROR)
+                                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+                                               .build();
+               } finally {
+                       // log success or failure
+                       if (ex != null) {
+                               ErrorLogHelper.logException(ex);
+                       }
+               }
+               return response;
+       }
+       
+       /**
+        * Gets the model query response.
+        *
+        * @param headers the headers
+        * @param req the req
+        * @param inboundPayload the inbound payload
+        * @param action the action
+        * @return the model query response
+        */
+       /* ---------------- Start Named Query --------------------- */
+       @POST
+       @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+       @Path(MODEL_QUERY)
+       public Response getModelQueryResponse(@Context HttpHeaders headers,
+                                                                               @Context HttpServletRequest req,
+                                                                               String inboundPayload,
+                                                                               @QueryParam("action") String action) {
+               AAIException ex = null;
+               Response response = null;
+               String fromAppId = null;
+               String transId = null;
+               String rqstTm = genDate();
+               ArrayList<String> templateVars = new ArrayList<String>();       
+               try { 
+                       fromAppId = getFromAppId(headers);
+                       transId = getTransId(headers);
+                       
+                       AAIExtensionMap aaiExtMap = new AAIExtensionMap();                                              
+                       aaiExtMap.setHttpHeaders(headers);
+                       aaiExtMap.setServletRequest(req);
+                       aaiExtMap.setApiVersion(AAIApiVersion.get());
+                       aaiExtMap.setFromAppId(fromAppId);
+                       aaiExtMap.setTransId(transId);
+                       
+                       String realTime = headers.getRequestHeaders().getFirst("Real-Time");
+                       //only consider header value for search         
+                       DBConnectionType type = this.determineConnectionType("force-cache", realTime);
+                       
+                       SearchGraph searchGraph = new SearchGraph();
+                       if (action != null && action.equalsIgnoreCase("DELETE")) { 
+                               response = searchGraph.executeModelOperation(fromAppId, transId, inboundPayload, type, true, aaiExtMap);
+                       } else {
+                               response = searchGraph.executeModelOperation(fromAppId, transId, inboundPayload, type, false, aaiExtMap);
+                       }
+                       String respTm = genDate();
+                       logTransaction(fromAppId, transId, "POSTMODELQUERYRESPONSE",
+                                       req.getRequestURI(), rqstTm, respTm, "", response);
+                       
+               } catch (AAIException e) {
+                       // send error response
+                       ex = e;
+                       templateVars.add("POST Search");
+                       templateVars.add("getModelQueryResponse");
+                       response =  Response
+                                               .status(e.getErrorObject().getHTTPResponseCode())
+                                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
+                                               .build();
+               } catch (Exception e) {
+                       // send error response
+                       ex = new AAIException("AAI_4000", e);
+                       templateVars.add("POST Search");
+                       templateVars.add("getModelQueryResponse");
+                       response = Response
+                                               .status(Status.INTERNAL_SERVER_ERROR)
+                                               .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+                                               .build();
+               } finally {
+                       // log success or failure
+                       if (ex != null) {
+                               ErrorLogHelper.logException(ex);
+                       }
+               }
+               return response;
+       }
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/QueryProcessorType.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/QueryProcessorType.java
new file mode 100644 (file)
index 0000000..33d7a90
--- /dev/null
@@ -0,0 +1,27 @@
+/*-
+ * ============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;
+
+public enum QueryProcessorType {
+
+       GREMLIN_SERVER,
+       LOCAL_GROOVY
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/SearchProvider.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/SearchProvider.java
new file mode 100644 (file)
index 0000000..d6712ce
--- /dev/null
@@ -0,0 +1,269 @@
+/*-
+ * ============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.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.UriInfo;
+
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+
+import org.openecomp.aai.db.props.AAIProperties;
+import org.openecomp.aai.dbgraphmap.SearchGraph;
+import org.openecomp.aai.dbmap.DBConnectionType;
+import org.openecomp.aai.domain.model.AAIResource;
+import org.openecomp.aai.domain.model.AAIResources;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.extensions.AAIExtensionMap;
+import org.openecomp.aai.ingestModel.IngestModelMoxyOxm;
+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.logging.ErrorLogHelper;
+import org.openecomp.aai.restcore.RESTAPI;
+import org.openecomp.aai.serialization.db.DBSerializer;
+import org.openecomp.aai.serialization.engines.QueryStyle;
+import org.openecomp.aai.serialization.engines.TitanDBEngine;
+import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
+import org.openecomp.aai.serialization.queryformats.utils.UrlBuilder;
+import org.openecomp.aai.util.AAIApiVersion;
+
+/**
+ * Implements the search subdomain in the REST API. All API calls must include
+ * X-FromAppId and X-TransactionId in the header.
+ * 
+ *
+ */
+
+@Path("/{version: v2|v[789]|v1[0]|latest}/search")
+public class SearchProvider extends RESTAPI {
+       
+       protected static String authPolicyFunctionName = "search";
+
+       public static final String GENERIC_QUERY = "/generic-query";
+
+       public static final String NODES_QUERY = "/nodes-query";
+
+       /**
+        * Gets the generic query response.
+        *
+        * @param headers the headers
+        * @param req the req
+        * @param startNodeType the start node type
+        * @param startNodeKeyParams the start node key params
+        * @param includeNodeTypes the include node types
+        * @param depth the depth
+        * @return the generic query response
+        */
+       /* ---------------- Start Generic Query --------------------- */
+       @GET
+       @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+       @Path(GENERIC_QUERY)
+       public Response getGenericQueryResponse(@Context HttpHeaders headers,
+                                                                                       @Context HttpServletRequest req,
+                                                                                       @QueryParam("start-node-type") final String startNodeType,
+                                                                                       @QueryParam("key") final List<String> startNodeKeyParams,
+                                                                                       @QueryParam("include") final List<String> includeNodeTypes,
+                                                                                       @QueryParam("depth") final int depth,
+                                                                                       @PathParam("version")String versionParam
+                                                                                       ) {
+               
+               AAIException ex = null;
+               Response searchResult = null;
+               String fromAppId = null;
+               String transId = null;
+               String rqstTm = genDate();
+               ArrayList<String> templateVars = new ArrayList<String>();
+               try { 
+                       fromAppId = getFromAppId(headers);
+                       transId = getTransId(headers);
+                       String realTime = headers.getRequestHeaders().getFirst("Real-Time");
+                       //only consider header value for search         
+                       DBConnectionType type = this.determineConnectionType("force-cache", realTime);
+                       final Version version;
+                       if (versionParam.equals("latest")) {
+                               version = AAIProperties.LATEST;
+                       } else {
+                               version = Version.valueOf(versionParam);
+                       }
+                       final ModelType factoryType = ModelType.MOXY;
+                       Loader loader = LoaderFactory.createLoaderForVersion(factoryType, version);
+                       TransactionalGraphEngine dbEngine = new TitanDBEngine(
+                                       QueryStyle.TRAVERSAL,
+                                       type,
+                                       loader);
+                       DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
+                       UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer);
+                       SearchGraph searchGraph = new SearchGraph();
+                       searchResult = searchGraph.runGenericQuery(
+                                                                                                          headers,
+                                                                                                          startNodeType,
+                                                                                                          startNodeKeyParams,
+                                                                                                          includeNodeTypes, 
+                                                                                                          depth,
+                                                                                                          dbEngine,
+                                                                                                          loader,
+                                                                                                          urlBuilder
+                                                                                                          
+                                                                                                          );
+       
+                       String respTm = genDate();
+                       logTransaction(fromAppId, transId,
+                                       "GETGENERICQUERYRESPONSE", req.getRequestURI(), rqstTm, respTm,
+                                       "", searchResult);
+               
+               } catch (AAIException e) { 
+                       // send error response
+                       ex = e;
+                       templateVars.add("GET Search");
+                       templateVars.add("getGenericQueryResponse");
+                       searchResult =  Response
+                                                       .status(e.getErrorObject().getHTTPResponseCode())
+                                                       .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
+                                                       .build();
+               } catch (Exception e) {
+                       // send error response
+                       ex = new AAIException("AAI_4000", e);
+                       templateVars.add("GET Search");
+                       templateVars.add("getGenericQueryResponse");
+                       searchResult = Response
+                                                       .status(Status.INTERNAL_SERVER_ERROR)
+                                                       .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+                                                       .build();
+               } finally {
+                       // log success or failure
+                       if (ex != null){
+                               ErrorLogHelper.logException(ex);
+                       }
+               }
+
+               return searchResult;
+       }
+
+       /* ---------------- End Generic Query --------------------- */
+
+       /**
+        * Gets the nodes query response.
+        *
+        * @param headers the headers
+        * @param req the req
+        * @param searchNodeType the search node type
+        * @param edgeFilterList the edge filter list
+        * @param filterList the filter list
+        * @return the nodes query response
+        */
+       /* ---------------- Start Nodes Query --------------------- */
+       @GET
+       @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+       @Path(NODES_QUERY)
+       public Response getNodesQueryResponse(@Context HttpHeaders headers,
+                                                                                       @Context HttpServletRequest req,
+                                                                                       @QueryParam("search-node-type") final String searchNodeType,
+                                                                                       @QueryParam("edge-filter") final List<String> edgeFilterList, 
+                                                                                       @QueryParam("filter") final List<String> filterList,
+                                                                                       @PathParam("version")String versionParam) {
+               AAIException ex = null;
+               Response searchResult = null;
+               String fromAppId = null;
+               String transId = null;
+               String rqstTm = genDate();
+               ArrayList<String> templateVars = new ArrayList<String>();       
+               try { 
+                       fromAppId = getFromAppId(headers);
+                       transId = getTransId(headers);
+                       String realTime = headers.getRequestHeaders().getFirst("Real-Time");
+                       //only consider header value for search         
+                       DBConnectionType type = this.determineConnectionType("force-cache", realTime);
+                       
+                       final Version version;
+                       if (versionParam.equals("latest")) {
+                               version = AAIProperties.LATEST;
+                       } else {
+                               version = Version.valueOf(versionParam);
+                       }
+                       final ModelType factoryType = ModelType.MOXY;
+                       Loader loader = LoaderFactory.createLoaderForVersion(factoryType, version);
+                       TransactionalGraphEngine dbEngine = new TitanDBEngine(
+                                       QueryStyle.TRAVERSAL,
+                                       type,
+                                       loader);
+                       DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
+                       UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer);
+                       SearchGraph searchGraph = new SearchGraph();
+                       
+                       searchResult = searchGraph.runNodesQuery(headers,
+                                                                                                       searchNodeType,
+                                                                                                       edgeFilterList, 
+                                                                                                       filterList,
+                                                                                                       dbEngine,
+                                                                                                       loader,
+                                                                                                       urlBuilder);
+       
+                       String respTm = genDate();
+                       logTransaction(fromAppId, transId, "GETNODESQUERYRESPONSE",
+                                       req.getRequestURI(), rqstTm, respTm, "", searchResult);
+               } catch (AAIException e) { 
+                       // send error response
+                       ex = e;
+                       templateVars.add("GET Search");
+                       templateVars.add("getNodesQueryResponse");
+                       searchResult =  Response
+                                                       .status(e.getErrorObject().getHTTPResponseCode())
+                                                       .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
+                                                       .build();
+               } catch (Exception e) {
+                       // send error response
+                       ex = new AAIException("AAI_4000", e);
+                       templateVars.add("GET Search");
+                       templateVars.add("getNodesQueryResponse");
+                       searchResult = Response
+                                                       .status(Status.INTERNAL_SERVER_ERROR)
+                                                       .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars))
+                                                       .build();
+               } finally {
+                       // log success or failure
+                       if (ex != null){
+                               ErrorLogHelper.logException(ex);
+                       }
+               }
+               return searchResult;
+       }
+
+
+       
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/ueb/NotificationEvent.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/ueb/NotificationEvent.java
new file mode 100644 (file)
index 0000000..389d296
--- /dev/null
@@ -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.ueb;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.Version;
+import org.openecomp.aai.util.StoreNotificationEvent;
+
+/**
+ * The Class NotificationEvent.
+ */
+public class NotificationEvent {
+
+       private Loader loader = null;
+       
+       private Introspector eventHeader = null;
+       
+       private Introspector obj = null;
+       
+       /**
+        * Instantiates a new notification event.
+        *
+        * @param version the version
+        * @param eventHeader the event header
+        * @param obj the obj
+        */
+       public NotificationEvent (Loader loader, Introspector eventHeader, Introspector obj) {
+               this.loader = loader;
+               this.eventHeader = eventHeader;
+               this.obj = obj;
+       }
+       
+       /**
+        * Trigger.
+        *
+        * @throws AAIException the AAI exception
+        */
+       public void trigger() throws AAIException {
+               
+               StoreNotificationEvent sne = new StoreNotificationEvent();
+               
+               sne.storeEvent(loader, eventHeader, obj);
+
+       }
+       
+       /**
+        * Gets the notification version.
+        *
+        * @return the notification version
+        */
+       public Version getNotificationVersion() {
+               return loader.getVersion();
+       }
+       
+       /**
+        * Gets the event header.
+        *
+        * @return the event header
+        */
+       public Introspector getEventHeader() {
+               return eventHeader;
+       }
+       
+       /**
+        * Gets the obj.
+        *
+        * @return the obj
+        */
+       public Introspector getObj() {
+               return obj;
+       }
+       
+       
+       
+       
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/ueb/UEBNotification.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/ueb/UEBNotification.java
new file mode 100644 (file)
index 0000000..397082f
--- /dev/null
@@ -0,0 +1,178 @@
+/*-
+ * ============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.ueb;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.openecomp.aai.db.props.AAIProperties;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.LoaderFactory;
+import org.openecomp.aai.introspection.Version;
+import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.openecomp.aai.introspection.exceptions.AAIUnmarshallingException;
+import org.openecomp.aai.parsers.uri.URIToObject;
+import org.openecomp.aai.util.AAIConfig;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+/**
+ * The Class UEBNotification.
+ */
+public class UEBNotification {
+
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(UEBNotification.class);
+
+       private Loader currentVersionLoader = null;
+       protected List<NotificationEvent> events = null;
+       private String urlBase = null;
+       private Version notificationVersion = null;
+       
+       /**
+        * Instantiates a new UEB notification.
+        *
+        * @param loader the loader
+        */
+       public UEBNotification(Loader loader) {
+               events = new ArrayList<>();
+               currentVersionLoader = LoaderFactory.createLoaderForVersion(loader.getModelType(), AAIProperties.LATEST);
+               urlBase = AAIConfig.get("aai.server.url.base","");
+               notificationVersion = Version.valueOf(AAIConfig.get("aai.notification.current.version","v10"));
+       }
+       
+       
+       /**
+        * Creates the notification event.
+        *
+        * @param transactionId the X-TransactionId
+        * @param sourceOfTruth 
+        * @param status the status
+        * @param uri the uri
+        * @param obj the obj
+        * @throws AAIException the AAI exception
+        * @throws IllegalArgumentException the illegal argument exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public void createNotificationEvent(String transactionId, String sourceOfTruth, Status status, URI uri, Introspector obj, HashMap<String, Introspector> relatedObjects) throws AAIException, IllegalArgumentException, UnsupportedEncodingException {
+               
+               String action = "UPDATE";
+               
+               if (status.equals(Status.CREATED)) {
+                       action = "CREATE";
+               } else if (status.equals(Status.OK)) {
+                       action = "UPDATE";
+               } else if (status.equals(Status.NO_CONTENT)) {
+                       action = "DELETE";
+               }
+
+               try {
+                       Introspector eventHeader = currentVersionLoader.introspectorFromName("notification-event-header");
+                       URIToObject parser = new URIToObject(currentVersionLoader, uri, relatedObjects);
+
+               String entityLink = "";
+               if (uri.toString().startsWith("/")) {
+                       entityLink = urlBase + notificationVersion + uri;
+               } else {
+                       entityLink = urlBase + notificationVersion + "/" + uri;
+               }
+               
+
+                       eventHeader.setValue("entity-link", entityLink);
+                       eventHeader.setValue("action", action);
+                       eventHeader.setValue("entity-type", obj.getDbName());
+                       eventHeader.setValue("top-entity-type", parser.getTopEntityName());
+                       eventHeader.setValue("source-name", sourceOfTruth);
+                       eventHeader.setValue("version", notificationVersion.toString());
+                       eventHeader.setValue("id", transactionId);
+
+                       List<Object> parentList = parser.getParentList();
+                       parentList.clear();
+
+                       if (!parser.getTopEntity().equals(parser.getEntity())) {
+                               Introspector child = obj;
+                               if (!parser.getLoader().getVersion().equals(obj.getVersion())) {
+                                       String json = obj.marshal(false);
+                                       child = parser.getLoader().unmarshal(parser.getEntity().getName(), json);
+                               }
+
+                               //wrap the child object in its parents
+                               parentList.add(child.getUnderlyingObject());
+                       }
+
+                       final Introspector eventObject;
+
+                       //convert to most resent version
+                       if (!parser.getLoader().getVersion().equals(currentVersionLoader.getVersion())) {
+                               String json = "";
+                               if (parser.getTopEntity().equals(parser.getEntity())) {
+                                       //convert the parent object passed in
+                                       json = obj.marshal(false);
+                                       eventObject = currentVersionLoader.unmarshal(obj.getName(), json);
+                               } else {
+                                       //convert the object created in the parser
+                                       json = parser.getTopEntity().marshal(false);
+                                       eventObject = currentVersionLoader.unmarshal(parser.getTopEntity().getName(), json);
+                               }
+                       } else {
+                               if (parser.getTopEntity().equals(parser.getEntity())) {
+                                       //take the top level parent object passed in
+                                       eventObject = obj;
+                               } else {
+                                       //take the wrapped child objects (ogres are like onions)
+                                       eventObject = parser.getTopEntity();
+                               }
+                       }
+
+                       final NotificationEvent event = new NotificationEvent(currentVersionLoader, eventHeader, eventObject);
+                       events.add(event);
+               } catch (AAIUnknownObjectException e) {
+                       throw new RuntimeException("Fatal error - notification-event-header object not found!");
+               } catch (AAIUnmarshallingException e) {
+                       LOGGER.error("Unmarshalling error occurred while generating UEBNotification", e);
+               }
+       }
+       
+       /**
+        * Trigger events.
+        *
+        * @throws AAIException the AAI exception
+        */
+       public void triggerEvents() throws AAIException {
+               for (NotificationEvent event : events) {
+                       event.trigger();
+               }
+               events.clear();
+       }
+       
+       public List<NotificationEvent> getEvents() {
+               return this.events;
+       }
+       
+       
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/util/EchoResponse.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/util/EchoResponse.java
new file mode 100644 (file)
index 0000000..6d01435
--- /dev/null
@@ -0,0 +1,121 @@
+/*-
+ * ============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.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import org.openecomp.aai.restcore.RESTAPI;
+
+/**
+ * The Class EchoResponse.
+ */
+public class EchoResponse extends RESTAPI {
+       
+       protected static String authPolicyFunctionName = "util";
+               
+       public static final String echoPath = "/util/echo";
+
+       /**
+        * Simple health-check API that echos back the X-FromAppId and X-TransactionId to clients.
+        * If there is a query string, a transaction gets logged into hbase, proving the application is connected to the data store.
+        * If there is no query string, no transacction logging is done to hbase.
+        *
+        * @param headers the headers
+        * @param req the req
+        * @param myAction if exists will cause transaction to be logged to hbase
+        * @return the response
+        */
+       @GET
+       @Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+       @Path(echoPath)
+       public Response echoResult(@Context HttpHeaders headers, @Context HttpServletRequest req,
+                       @QueryParam("action") String myAction) {
+               Response response = null;
+               
+               AAIException ex = null;
+               String fromAppId = null;
+               String transId = null;
+               
+               try { 
+                       fromAppId = getFromAppId(headers );
+                       transId = getTransId(headers);
+               } catch (AAIException e) { 
+                       ArrayList<String> templateVars = new ArrayList<String>();
+                       templateVars.add("PUT uebProvider");
+                       templateVars.add("addTopic");
+                       return Response
+                                       .status(e.getErrorObject().getHTTPResponseCode())
+                                       .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
+                                       .build();
+               }
+               
+               try {
+                       
+                       HashMap<AAIException, ArrayList<String>> exceptionList = new HashMap<AAIException, ArrayList<String>>();
+                                       
+                       ArrayList<String> templateVars = new ArrayList<String>();
+                       templateVars.add(fromAppId);
+                       templateVars.add(transId);
+               
+                       exceptionList.put(new AAIException("AAI_0002", "OK"), templateVars);
+                               
+                       response = Response.status(Status.OK)
+                                       .entity(ErrorLogHelper.getRESTAPIInfoResponse(
+                                                       headers.getAcceptableMediaTypes(), exceptionList))
+                                                       .build();
+                       
+               } catch (Exception e) {
+                       ex = new AAIException("AAI_4000", e);
+                       ArrayList<String> templateVars = new ArrayList<String>();
+                       templateVars.add(Action.GET.name());
+                       templateVars.add(fromAppId +" "+transId);
+
+                       response = Response
+                                       .status(Status.INTERNAL_SERVER_ERROR)
+                                       .entity(ErrorLogHelper.getRESTAPIErrorResponse(
+                                                       headers.getAcceptableMediaTypes(), ex,
+                                                       templateVars)).build();
+
+               } finally {
+                       if (ex != null) {
+                               ErrorLogHelper.logException(ex);
+                       }
+
+               }
+               
+               return response;
+       }
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/util/LogFormatTools.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/util/LogFormatTools.java
new file mode 100644 (file)
index 0000000..d6fcd67
--- /dev/null
@@ -0,0 +1,36 @@
+/*-
+ * ============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.util;
+
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class LogFormatTools {
+
+       private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
+       private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern(DATE_FORMAT)
+                                                                                                                                       .withZone(ZoneOffset.UTC);
+       
+       public static String getCurrentDateTime() {
+               return DTF.format(ZonedDateTime.now());
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/util/ValidateEncoding.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/util/ValidateEncoding.java
new file mode 100644 (file)
index 0000000..a09a317
--- /dev/null
@@ -0,0 +1,160 @@
+/*-
+ * ============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.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriInfo;
+
+import org.springframework.web.util.UriUtils;
+
+/**
+ * The Class ValidateEncoding.
+ */
+public class ValidateEncoding {
+
+       private final String encoding = "UTF-8";
+       
+       /**
+        * Instantiates a new validate encoding.
+        */
+       private ValidateEncoding() {
+               
+       }
+       
+       /**
+        * The Class Helper.
+        */
+       private static class Helper {
+               
+               /** The Constant INSTANCE. */
+               private static final ValidateEncoding INSTANCE = new ValidateEncoding();
+       }
+       
+       /**
+        * Gets the single instance of ValidateEncoding.
+        *
+        * @return single instance of ValidateEncoding
+        */
+       public static ValidateEncoding getInstance() {
+               return Helper.INSTANCE;
+       }       
+       
+       /**
+        * Validate.
+        *
+        * @param uri the uri
+        * @return true, if successful
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public boolean validate(URI uri) throws UnsupportedEncodingException {
+               boolean result = true;
+               if (!validatePath(uri.getRawPath())) {
+                       result = false;
+               }
+               /*if (!validateQueryParams(uri.getRawQuery())) {
+                       result = false;
+               } //TODO
+               */
+               
+               return result;
+       }
+       
+       /**
+        * Validate.
+        *
+        * @param info the info
+        * @return true, if successful
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public boolean validate(UriInfo info) throws UnsupportedEncodingException {
+               boolean result = true;
+               if (!validatePath(info.getPath(false))) {
+                       result = false;
+               }
+               if (!validateQueryParams(info.getQueryParameters(false))) {
+                       result = false;
+               }
+               
+               return result;
+       }
+       
+       /**
+        * Validate path.
+        *
+        * @param path the path
+        * @return true, if successful
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       private boolean validatePath(String path) throws UnsupportedEncodingException {
+               String[] segments = path.split("/");
+               boolean valid = true;
+               for (String segment : segments) {
+                       if (!this.checkEncoding(segment)) {
+                               valid = false;
+                       }
+               }
+               
+               return valid;
+               
+       }
+       
+       /**
+        * Validate query params.
+        *
+        * @param params the params
+        * @return true, if successful
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       private boolean validateQueryParams(MultivaluedMap<String, String> params) throws UnsupportedEncodingException {
+               boolean valid = true;
+               
+               for (String key : params.keySet()) {
+                       if (!this.checkEncoding(key)) {
+                               valid = false;
+                       }
+                       for (String item : params.get(key)) {
+                               if (!this.checkEncoding(item)) {
+                                       valid = false;
+                               }
+                       }
+               }
+               return valid;
+       }
+       
+       /**
+        * Check encoding.
+        *
+        * @param segment the segment
+        * @return true, if successful
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       private boolean checkEncoding(String segment) throws UnsupportedEncodingException {
+               boolean result = false;
+               String decode = UriUtils.decode(segment, encoding);
+               String encode = UriUtils.encode(decode, encoding);
+               result = segment.equals(encode);
+               
+               return result;
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/transforms/Converter.java b/aai-traversal/src/main/java/org/openecomp/aai/transforms/Converter.java
new file mode 100644 (file)
index 0000000..44a0222
--- /dev/null
@@ -0,0 +1,25 @@
+/*-
+ * ============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.transforms;
+
+public interface Converter {
+    String convert(String input);
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/transforms/LowerCamelToLowerHyphenConverter.java b/aai-traversal/src/main/java/org/openecomp/aai/transforms/LowerCamelToLowerHyphenConverter.java
new file mode 100644 (file)
index 0000000..a31da05
--- /dev/null
@@ -0,0 +1,34 @@
+/*-
+ * ============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.transforms;
+
+import com.google.common.base.CaseFormat;
+
+public class LowerCamelToLowerHyphenConverter implements Converter {
+
+    @Override
+    public String convert(String input) {
+        if(input == null){
+            return null;
+        }
+        return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, input);
+    }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/transforms/LowerHyphenToLowerCamelConverter.java b/aai-traversal/src/main/java/org/openecomp/aai/transforms/LowerHyphenToLowerCamelConverter.java
new file mode 100644 (file)
index 0000000..784adbe
--- /dev/null
@@ -0,0 +1,81 @@
+/*-
+ * ============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.transforms;
+
+/**
+ * <b>LowerHyphenToLowerCamelConverter</b> is the converter to use
+ * for converting from the lower hyphen to lower camel case
+ * <p>
+ * Examples:
+ *  lower-test => lowerTest
+ *  lower-Test => lowerTest
+ *  lowerTest  => lowerTest
+ *  lower-test-val => lowerTestVal
+ * <p>
+ *
+ */
+public class LowerHyphenToLowerCamelConverter implements Converter {
+
+    /**
+     * Converts the dash formatted string into a camel case string
+     * Ensure that the capitalization is not lost during this conversion
+     * <p>
+     * Loops through each character in the string
+     * checks if the current character is '-' and if it is then sets the
+     * boolean isPreviousCharDash to true and continues to the next iteration
+     * If the character is not '-', then checks if the previous character is dash
+     * If it is, then it will upper case the current character and appends to the builder
+     * Otherwise, it will just append the current character without any modification
+     *
+     * @param input the input string to convert to camel case
+     * @return a string that is converted to camel case
+     *          if the input is null, then it returns null
+     */
+    @Override
+    public String convert(String input) {
+        if(input == null){
+            return null;
+        }
+
+        int size = input.length();
+        StringBuilder builder = new StringBuilder(size);
+
+        boolean isPreviousCharDash = false;
+
+        for(int index = 0; index < size; ++index){
+            char ch = input.charAt(index);
+
+            if(ch == '-'){
+                isPreviousCharDash = true;
+                continue;
+            }
+            if(isPreviousCharDash){
+                builder.append(Character.toUpperCase(ch));
+                isPreviousCharDash = false;
+            } else{
+                builder.append(ch);
+            }
+        }
+
+        return builder.toString();
+    }
+
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/transforms/MapTraverser.java b/aai-traversal/src/main/java/org/openecomp/aai/transforms/MapTraverser.java
new file mode 100644 (file)
index 0000000..7695240
--- /dev/null
@@ -0,0 +1,87 @@
+/*-
+ * ============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.transforms;
+
+
+import joptsimple.internal.Objects;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MapTraverser {
+
+    private Converter converter;
+
+    public MapTraverser(Converter converter){
+        this.converter = converter;
+    }
+
+    public Map<String, Object> convertKeys(Map<String, Object> map){
+
+        Objects.ensureNotNull(map);
+
+        Map<String, Object> modifiedMap = new HashMap<String, Object>();
+        convertKeys(map, modifiedMap);
+
+        return modifiedMap;
+    }
+
+    private Map<String, Object> convertKeys(Map<String, Object> original, Map<String, Object> modified){
+
+        for(Map.Entry<String, Object> entry : original.entrySet()){
+            String key = entry.getKey();
+            key = converter.convert(key);
+            Object value = entry.getValue();
+            if(value instanceof Map){
+                modified.put(key, convertKeys((Map<String, Object>)value, new HashMap<String, Object>()));
+            } else if(value instanceof List){
+                modified.put(key, convertKeys((List<Object>) value));
+            } else {
+                modified.put(key, value);
+            }
+        }
+
+        return modified;
+    }
+
+    public List<Object> convertKeys(List<Object> list){
+
+        List<Object> modifiedList = new ArrayList<Object>();
+        if(list != null && list.size() > 0){
+
+            for(Object o : list){
+                if(o instanceof Map){
+                    Map<String, Object> map = (Map<String, Object>) o;
+                    modifiedList.add(convertKeys(map));
+                } else if(o instanceof List){
+                    List<Object> l = (List<Object>) o;
+                    modifiedList.add(convertKeys(l));
+                } else {
+                    modifiedList.add(o);
+                }
+            }
+        }
+
+        return modifiedList;
+    }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/util/AAIAppServletContextListener.java b/aai-traversal/src/main/java/org/openecomp/aai/util/AAIAppServletContextListener.java
new file mode 100644 (file)
index 0000000..97b7edb
--- /dev/null
@@ -0,0 +1,104 @@
+/*-
+ * ============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.util;
+
+import java.io.IOException;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.activemq.broker.BrokerService;
+
+import org.openecomp.aai.dbmap.AAIGraph;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.ModelInjestor;
+import org.openecomp.aai.logging.ErrorLogHelper;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class AAIAppServletContextListener implements ServletContextListener {
+
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(AAIAppServletContextListener.class.getName());     
+       
+       private BrokerService broker = new BrokerService();
+
+       /**
+        * Destroys Context
+        * 
+        * @param arg0 the ServletContextEvent
+        */
+       public void contextDestroyed(ServletContextEvent arg0) {                
+               LOGGER.info("AAIGraph shutting down");
+               AAIGraph.getInstance().graphShutdown();
+               LOGGER.info("AAIGraph shutdown");
+
+               try {
+                       broker.stop();
+               } catch (Exception e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * Initializes Context
+        * 
+        * @param arg0 the ServletContextEvent
+        */
+       public void contextInitialized(ServletContextEvent arg0) {
+               System.setProperty("org.openecomp.aai.serverStarted", "false");
+               LOGGER.info("***AAI Server initialization started...");
+
+               try {
+                       LOGGER.info("Loading aaiconfig.properties");
+                       AAIConfig.init();
+
+                       LOGGER.info("Loading error.properties");
+                       ErrorLogHelper.loadProperties();
+
+                       LOGGER.info("Loading graph database");
+
+                       AAIGraph.getInstance();
+                       ModelInjestor.getInstance();
+
+                       // Jsm internal broker for aai events
+                       broker = new BrokerService();
+                       broker.addConnector("tcp://localhost:61446");
+                       broker.setPersistent(false);
+                       broker.setUseJmx(false);
+                       broker.setSchedulerSupport(false);
+                       broker.start();
+
+                       LOGGER.info("A&AI Server initialization succcessful.");
+                       System.setProperty("org.openecomp.aai.serverStarted", "true");
+
+               } catch (AAIException e) {
+                       ErrorLogHelper.logException(e);
+                       throw new RuntimeException("AAIException caught while initializing A&AI server", e);
+               } catch (IOException e) {
+                       ErrorLogHelper.logError("AAI_4000", e.getMessage());
+                       throw new RuntimeException("IOException caught while initializing A&AI server", e);
+               } catch (Exception e) {
+                       LOGGER.error("Unknown failure while initializing A&AI Server", e);
+                       throw new RuntimeException("Unknown failure while initializing A&AI server", e);
+               }
+       }
+}
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/util/RestURL.java b/aai-traversal/src/main/java/org/openecomp/aai/util/RestURL.java
new file mode 100644 (file)
index 0000000..7c70929
--- /dev/null
@@ -0,0 +1,704 @@
+/*-
+ * ============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.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.springframework.web.util.UriUtils;
+
+import org.openecomp.aai.domain.model.AAIResource;
+import org.openecomp.aai.domain.model.AAIResourceKey;
+import org.openecomp.aai.domain.model.AAIResourceKeys;
+import org.openecomp.aai.domain.model.AAIResources;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.extensions.AAIExtensionMap;
+import org.openecomp.aai.ingestModel.DbMaps;
+import org.openecomp.aai.ingestModel.IngestModelMoxyOxm;
+import com.google.common.base.CaseFormat;
+import com.thinkaurelius.titan.core.TitanEdge;
+import com.thinkaurelius.titan.core.TitanTransaction;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+public class RestURL {
+       
+       
+       /*
+        * method returns a REST URL for the given node based on its nodetype and key
+        * information 
+        */     
+
+       /**
+        * Gets the.
+        *
+        * @param graph the graph
+        * @param node the node
+        * @param apiVersion the api version
+        * @param isLegacyVserverUEB the is legacy vserver UEB
+        * @param isCallbackurl the is callbackurl
+        * @return the string
+        * @throws AAIException the AAI exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public static String get(TitanTransaction graph, TitanVertex node, String apiVersion, Boolean isLegacyVserverUEB, Boolean isCallbackurl) throws AAIException, UnsupportedEncodingException
+       {
+               String nodeType = node.<String>property("aai-node-type").orElse(null);
+               String url = "";
+       String currentNodeType = nodeType;
+       Boolean noMoreDependentNodes = true;
+       TitanVertex currentNode = node;
+
+       // if the caller supplies an apiVersion we'll use it, otherwise we'll just
+       // reflect back from the called URI
+               if (apiVersion == null) { 
+                       apiVersion = AAIApiVersion.get();
+       }
+                       
+       String nodeURI = null;
+       if (Boolean.parseBoolean(AAIConfig.get("aai.use.unique.key", "false")))
+               nodeURI = node.<String>property("aai-unique-key").orElse(null);
+       
+               if (nodeURI != null && !nodeURI.equals("")) {
+               if (isCallbackurl) {
+                       url = AAIConfig.get(AAIConstants.AAI_GLOBAL_CALLBACK_URL) + apiVersion + "/" + nodeURI;
+                       return url;
+               } else {
+                       url = AAIApiServerURLBase.get() + apiVersion + "/" + nodeURI;
+                               return url;
+               }
+               }
+               
+               // TODO
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+       // add the url component for the dependent on nodes for the node passed in
+       while (noMoreDependentNodes) {
+               Collection <String> depNodeTypeColl =  dbMaps.NodeDependencies.get(currentNodeType);
+               Iterator <String> depNodeTypeListIterator = (Iterator<String>) depNodeTypeColl.iterator();
+               if (!depNodeTypeListIterator.hasNext()) {
+                       noMoreDependentNodes = false;
+                       break;
+               }
+               
+                   // Look for IN edges for the current Node and find its Parent - and make it the current Node
+               boolean foundParent = false;
+                       Iterator <Edge> inEdges = currentNode.edges(Direction.IN);
+               while( inEdges.hasNext() ){
+                       TitanEdge inEdge = (TitanEdge) inEdges.next();
+                       Boolean inEdgeIsParent = inEdge.<Boolean>property("isParent").orElse(null);
+                       if( inEdgeIsParent != null && inEdgeIsParent ){
+                               foundParent = true;
+                               currentNode = (TitanVertex) inEdge.otherVertex(currentNode);
+                               break;
+                       }
+               }
+               
+               if (foundParent == false) { 
+                       break;
+               }
+               
+               // find the key(s) and add to the url
+               // first see what type of node the parent is - note some nodes can have one of many kinds of parents
+               String depNodeType = currentNode.<String>property("aai-node-type").orElse(null);
+               Collection <String> keyProps =  dbMaps.NodeKeyProps.get(depNodeType);
+                   Iterator <String> keyPropI = keyProps.iterator();
+                   
+                   String nodeUrl = null;
+                   String depNodeTypePlural = dbMaps.NodePlural.get(depNodeType);
+
+               if (depNodeTypePlural != null)
+               {
+                               nodeUrl = depNodeTypePlural + "/" + depNodeType + "/";
+                   }               
+                   
+                   while (keyPropI.hasNext()) {
+                       Object nodeKey = currentNode.<Object>property(keyPropI.next()).orElse(null);
+                       nodeUrl += RestURLEncoder.encodeURL(nodeKey.toString()) + "/";
+                   }
+                               
+               currentNodeType = depNodeType;  
+               
+                       url = nodeUrl + url;
+               }
+       // use the name space of the highest level of unique node since lots of children node types
+       // are common ex. l-interface is in the path for pserver and vpe
+               String urlNamespace = dbMaps.NodeNamespace.get(currentNodeType) + "/"; 
+               urlNamespace = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, urlNamespace);
+           
+       // add the url component for the node passed in
+       Collection <String> keyProps =  dbMaps.NodeKeyProps.get(nodeType);
+           Iterator <String> keyPropI = keyProps.iterator();
+           
+           String nodeUrl = null;
+               String nodeTypePlural = "";
+               nodeTypePlural = dbMaps.NodePlural.get(nodeType);
+           
+           
+       if (nodeTypePlural != null && !nodeTypePlural.equals("")){
+               nodeUrl = nodeTypePlural + "/" + nodeType + "/";
+       } else {
+               nodeUrl = nodeType + "/";
+       }
+
+           if (nodeType.equals("ipaddress")) { // this has 2 keys but API only uses port-or -address in URL
+               String nodeKey = node.<String>property("port-or-interface").orElse(null);
+               nodeUrl += RestURLEncoder.encodeURL(nodeKey) + "/";
+           } else {
+                   while (keyPropI.hasNext()) {
+                       Object nodeKey = node.<Object>property(keyPropI.next()).orElse(null);
+                       nodeUrl += RestURLEncoder.encodeURL(nodeKey.toString()) + "/";
+                   }
+           }
+           if (isCallbackurl) {
+               url = AAIConfig.get(AAIConstants.AAI_GLOBAL_CALLBACK_URL) + apiVersion + "/" + urlNamespace + url + nodeUrl;
+       } else {
+               url = AAIApiServerURLBase.get() + apiVersion + "/" + urlNamespace + url + nodeUrl;
+           }
+               return url;
+       }
+
+       /**
+        * Gets the search url.
+        *
+        * @param graph the graph
+        * @param node the node
+        * @param apiVersion the api version
+        * @return the search url
+        * @throws AAIException the AAI exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public static String getSearchUrl(TitanTransaction graph, TitanVertex node, String apiVersion) throws AAIException, UnsupportedEncodingException
+       {
+               String nodeType = node.<String>property("aai-node-type").orElse(null);
+               String url = "";
+       String currentNodeType = nodeType;
+       Boolean noMoreDependentNodes = true;
+       TitanVertex currentNode = node;
+       Boolean hasCloudRegion = false;
+
+       // if the caller supplies an apiVersion we'll use it, otherwise we'll just
+       // reflect back from the called URI
+               if (apiVersion == null) { 
+                       apiVersion = AAIApiVersion.get();
+       }
+               
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP));
+               
+       // add the url component for the dependent on nodes for the node passed in
+       while (noMoreDependentNodes) {
+               Collection <String> depNodeTypeColl =  dbMaps.NodeDependencies.get(currentNodeType);
+               Iterator <String> depNodeTypeListIterator = (Iterator<String>) depNodeTypeColl.iterator();
+               if (!depNodeTypeListIterator.hasNext()) {
+                       noMoreDependentNodes = false;
+                       break;
+               }
+               
+                   // Look for IN edges for the current Node and find its Parent - and make it the current Node
+               boolean foundParent = false;
+                       Iterator <Edge> inEdges = currentNode.edges(Direction.IN);
+               while( inEdges.hasNext() ){
+                       TitanEdge inEdge = (TitanEdge) inEdges.next();
+                       Boolean inEdgeIsParent = inEdge.<Boolean>property("isParent").orElse(null);
+                       if( inEdgeIsParent != null && inEdgeIsParent ){
+                               foundParent = true;
+                               currentNode = inEdge.otherVertex(currentNode);
+                               break;
+                       }
+               }
+               
+               if (foundParent == false) { 
+                       break;
+               }
+               
+               // find the key(s) and add to the url
+               // first see what type of node the parent is - note some nodes can have one of many kinds of parents
+               String depNodeType = currentNode.<String>property("aai-node-type").orElse(null);
+               Collection <String> keyProps =  dbMaps.NodeKeyProps.get(depNodeType);
+                   Iterator <String> keyPropI = keyProps.iterator();
+                   
+                   String nodeUrl = null;
+                   String depNodeTypePlural = dbMaps.NodePlural.get(depNodeType);
+
+               if (depNodeTypePlural != null)
+                       nodeUrl = depNodeTypePlural + "/" + depNodeType + "/";
+
+                   while (keyPropI.hasNext()) {
+                       Object nodeKey = currentNode.<Object>property(keyPropI.next()).orElse(null);
+                       nodeUrl += RestURLEncoder.encodeURL(nodeKey.toString()) + "/";
+                   }
+                               
+               currentNodeType = depNodeType;  
+               
+                       url = nodeUrl + url;
+               }
+       // use the name space of the highest level of unique node since lots of children node types
+       // are common ex. l-interface is in the path for pserver and vpe
+               String urlNamespace = dbMaps.NodeNamespace.get(currentNodeType) + "/"; 
+               urlNamespace = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, urlNamespace);
+           
+       // add the url component for the node passed in
+       Collection <String> keyProps =  dbMaps.NodeKeyProps.get(nodeType);
+           Iterator <String> keyPropI = keyProps.iterator();
+           
+           String nodeUrl = null;
+               String nodeTypePlural = "";
+               nodeTypePlural = dbMaps.NodePlural.get(nodeType);
+           
+       if (nodeTypePlural != null && !nodeTypePlural.equals(""))
+               nodeUrl = nodeTypePlural + "/" + nodeType + "/";
+       else
+               nodeUrl = nodeType + "/";
+
+           if (nodeType.equals("ipaddress")) { // this has 2 keys but API only uses port-or -address in URL
+               String nodeKey = node.<String>property("port-or-interface").orElse(null);
+               nodeUrl += RestURLEncoder.encodeURL(nodeKey) + "/";
+           } else {
+                   while (keyPropI.hasNext()) {
+                       Object nodeKey = node.<Object>property(keyPropI.next()).orElse(null);
+                       nodeUrl += RestURLEncoder.encodeURL(nodeKey.toString()) + "/";
+                   }
+           }
+
+       String nodeVersion = dbMaps.NodeVersionInfoMap.get(nodeType);           
+       String urlVersion = null;
+       int nodeVerNum = Integer.parseInt(nodeVersion.substring(1));
+       int apiVerNum  = Integer.parseInt(apiVersion.substring(1));
+       
+               if (hasCloudRegion) {
+               if (apiVerNum < 7)
+                       urlVersion = "v7"; // or set to the latest version?
+               else 
+                       urlVersion = apiVersion;
+       } else {                                
+               if (nodeVerNum == apiVerNum || nodeVerNum < apiVerNum)
+                       urlVersion = apiVersion;                        
+               else 
+                       urlVersion = nodeVersion;
+       }                       
+       url = AAIApiServerURLBase.get() + urlVersion + "/" + urlNamespace + url + nodeUrl;
+       //remove the trailing "/"
+       url = url.substring(0, url.length()-1);
+               return url;
+       }
+       
+       /**
+        * Gets the.
+        *
+        * @param graph the graph
+        * @param node the node
+        * @return the string
+        * @throws AAIException the AAI exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public static String get(TitanTransaction graph, TitanVertex node) throws AAIException, UnsupportedEncodingException
+       {
+               return get(graph, node, null, false, false);
+       }
+       
+       /**
+        * Gets the.
+        *
+        * @param graph the graph
+        * @param node the node
+        * @param apiVersion the api version
+        * @return the string
+        * @throws AAIException the AAI exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public static String get(TitanTransaction graph, TitanVertex node, String apiVersion) throws AAIException, UnsupportedEncodingException
+       {
+               return get(graph, node, apiVersion, false, false);
+       }
+       
+       /**
+        * Gets the.
+        *
+        * @param graph the graph
+        * @param node the node
+        * @param apiVersion the api version
+        * @param isLegacyVserverUEB the is legacy vserver UEB
+        * @return the string
+        * @throws AAIException the AAI exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public static String get(TitanTransaction graph, TitanVertex node, String apiVersion, Boolean isLegacyVserverUEB) throws AAIException, UnsupportedEncodingException
+       {
+               return get(graph, node, apiVersion, isLegacyVserverUEB, false);
+       }
+       
+       /**
+        * Gets the key hashes.
+        *
+        * @param graph the graph
+        * @param node the node
+        * @return the key hashes
+        * @throws AAIException the AAI exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public static LinkedHashMap<String, Object> getKeyHashes(TitanTransaction graph, TitanVertex node) throws AAIException, UnsupportedEncodingException
+       {
+               return getKeyHashes(graph, node, null);
+       }
+       
+       /*
+        * method returns a Hash of Hashes for each parents keys for the given node based on its nodetype 
+        * Special cases for REST URLs:
+        *  - old URLS for vserver, ipaddress and volume node types for v2/v3
+        *  - images, flavor, vnic and l-interface node types will return new url
+        *  - nodetypes with multiple keys such as service capability
+        *  - nodetypes with multiple keys such as ipaddress where we use one key in the URL
+        *  - cvlan-tags and *list nodetypes - have special or no plurals - they get handled via the hash Map
+        */     
+
+       /**
+        * Gets the key hashes.
+        *
+        * @param graph the graph
+        * @param node the node
+        * @param apiVersion the api version
+        * @return the key hashes
+        * @throws AAIException the AAI exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public static LinkedHashMap <String,Object> getKeyHashes(TitanTransaction graph, TitanVertex node, String apiVersion) throws AAIException, UnsupportedEncodingException
+       {
+               String nodeType = node.<String>property("aai-node-type").orElse(null);
+       Boolean noMoreDependentNodes = true;
+       TitanVertex currentNode = node;
+     
+               if (apiVersion == null || apiVersion.equals("")) { 
+                       apiVersion = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP);
+       }
+               
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(apiVersion);
+               
+               // Hash of hashes of keys for each node and its ancestry
+               LinkedHashMap <String,Object> returnHash = new LinkedHashMap <String,Object> ();
+               
+       // create the hash for the keys for the node passed in
+       HashMap <String,Object> thisNodeHash = new HashMap <String,Object> ();
+       Collection <String> keyProps =  dbMaps.NodeKeyProps.get(nodeType);
+           Iterator <String> keyPropI = keyProps.iterator();
+           
+           if (nodeType.equals("ipaddress")) { // this has 2 keys but API only uses port-or -address in URL
+               String nodeKeyValue = node.<String>property("port-or-interface").orElse(null);
+               thisNodeHash.put("port-or-interface", nodeKeyValue);
+           } else {
+                   while (keyPropI.hasNext()) {
+                       String nodeKeyName = keyPropI.next();
+                       Object nodeKeyValue = node.<Object>property(nodeKeyName).orElse(null);
+                       thisNodeHash.put(nodeKeyName, nodeKeyValue);
+                       nodeKeyName =  nodeType + "." + nodeKeyName;
+                   }
+           }
+           returnHash.putAll(thisNodeHash);        
+                       
+       // create and add the hashes for the dependent nodes for the node passed in
+       while (noMoreDependentNodes) {
+//             Collection <String> depNodeTypeColl =  DbRules.NodeDependencies.get(currentNodeType);
+//             Iterator <String> depNodeTypeListIterator = (Iterator<String>) depNodeTypeColl.iterator();
+               HashMap <String,Object> depNodeHash = new HashMap <String,Object> ();
+//             
+//             if (!depNodeTypeListIterator.hasNext()) {
+//                     noMoreDependentNodes = false;
+//                     break;
+//             }
+               
+               boolean foundParent = false;
+               
+                   // Look for IN edges for the current Node and find its Parent - and make it the current Node
+                       Iterator <Edge> inEdges = currentNode.edges(Direction.IN);
+               while( inEdges.hasNext() ){
+                       TitanEdge inEdge = (TitanEdge) inEdges.next();
+                       Boolean inEdgeIsParent = inEdge.<Boolean>property("isParent").orElse(null);
+                       if( inEdgeIsParent != null && inEdgeIsParent ){
+                               currentNode = inEdge.otherVertex(currentNode);
+                               foundParent = true;
+                               break;
+                       }
+               }
+               if (foundParent == false) { 
+                       break;
+               }
+               
+               // find the key(s) and add to the url
+               // first see what type of node the parent is - note some nodes can have one of many kinds of parents
+               String depNodeType = currentNode.<String>property("aai-node-type").orElse(null);
+               keyProps =  dbMaps.NodeKeyProps.get(depNodeType);
+                   keyPropI = keyProps.iterator();
+                                   
+                   while (keyPropI.hasNext()) {
+                       String nodeKeyName = keyPropI.next();
+                       Object nodeKeyValue = currentNode.<Object>property(nodeKeyName).orElse(null);
+                       nodeKeyName = depNodeType + "." + nodeKeyName;
+                       // key name will be like tenant.tenant-id
+                       
+                       depNodeHash.put(nodeKeyName, nodeKeyValue);
+                   }
+                   returnHash.putAll(depNodeHash);             
+               }
+           
+               return returnHash;
+       }
+       
+       /*
+        * method returns a Hash of Hashes for each parents keys for the given node based on its nodeURI
+        * Special cases for REST URLs:
+        *  - images, flavor, vnic and l-interface node types will return new url
+        *  - nodetypes with multiple keys such as service capability
+        *  - nodetypes with multiple keys such as ipaddress where we use one key in the URL
+        *  - cvlan-tags and *list nodetypes - have special or no plurals - they get handled via the hash Map
+        */     
+
+       /**
+        * Gets the key hashes.
+        *
+        * @param nodeURI the node URI
+        * @return the key hashes
+        * @throws AAIException the AAI exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public static LinkedHashMap <String,Object> getKeyHashes(String nodeURI) throws AAIException, UnsupportedEncodingException
+       {
+               return getKeyHashes(nodeURI, null);
+               
+       }
+       
+       /**
+        * Gets the key hashes.
+        *
+        * @param nodeURI the node URI
+        * @param apiVersion the api version
+        * @return the key hashes
+        * @throws AAIException the AAI exception
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        */
+       public static LinkedHashMap <String,Object> getKeyHashes(String nodeURI, String apiVersion) throws AAIException, UnsupportedEncodingException
+       {
+               
+               if (apiVersion == null || apiVersion.equals(""))
+                       apiVersion = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP);
+                       
+               DbMaps dbMaps = IngestModelMoxyOxm.dbMapsContainer.get(apiVersion);
+               
+               // Hash of hashes of keys for each node and its ancestry
+               LinkedHashMap <String,Object> returnHash = new LinkedHashMap <String,Object> ();
+               
+               String path = nodeURI.replaceFirst("^/", "");           
+               Path p = Paths.get(path);
+               int index = p.getNameCount() - 2; // index of where we expect the node type to be
+               
+               // if the node type has one key
+               String currentNodeType = p.getName(index).toString();
+               // if the node type has two keys - this assumes max 2 keys
+               if (!dbMaps.NodeKeyProps.containsKey(currentNodeType))
+                       currentNodeType = p.getName(--index).toString();
+       
+       // create the hash for the keys for the node passed in
+       LinkedHashMap <String,Object> thisNodeHash = new LinkedHashMap <String,Object> ();
+       Collection <String> keyProps =  dbMaps.NodeKeyProps.get(currentNodeType);
+           Iterator <String> keyPropI = keyProps.iterator();
+       
+           if (currentNodeType.equals("ipaddress")) { // this has 2 keys but API only uses port-or -address in URL
+               String nodeKeyValue = p.getName(index + 1).toString();
+               thisNodeHash.put("port-or-interface", nodeKeyValue);
+           } else {
+               int j = 1;
+                   while (keyPropI.hasNext()) {
+                       String nodeKeyName = currentNodeType + "." + keyPropI.next();
+                       String nodeKeyValue = p.getName(index + j++).toString();
+                       thisNodeHash.put(nodeKeyName, nodeKeyValue);
+                   }
+           }
+           returnHash.putAll(thisNodeHash);        
+           if (!currentNodeType.contains("-list"))
+               index -= 3; 
+           else
+               index -= 2; // no plural in this case
+                       
+
+       // create and add the hashes for the dependent nodes for the node passed in
+           LinkedHashMap <String,Object> depNodeHash = new LinkedHashMap <String,Object> (); 
+           String depNodeType = null;
+       while (index >= 2) {
+               if (depNodeType == null) depNodeType = p.getName(index).toString();
+               //System.out.println("index=" + index);         
+               // if the node type has one key
+               currentNodeType = p.getName(index).toString();
+               // if the node type has two keys - this assumes max 2 keys
+               if (!dbMaps.NodeKeyProps.containsKey(currentNodeType))
+                       currentNodeType = p.getName(--index).toString();
+       
+               keyProps =  dbMaps.NodeKeyProps.get(currentNodeType);
+           keyPropI = keyProps.iterator();
+               
+           if (currentNodeType.equals("ipaddress")) { // this has 2 keys but API only uses port-or -address in URL
+               String nodeKeyValue = p.getName(index + 1).toString();
+               depNodeHash.put("port-or-interface", nodeKeyValue);
+           } else {
+               int j = 1;
+                   while (keyPropI.hasNext()) {
+                       String nodeKeyName = currentNodeType + "." + keyPropI.next();
+                       String nodeKeyValue = p.getName(index + j++).toString();
+                       depNodeHash.put(nodeKeyName, nodeKeyValue);
+                   }
+           }
+
+           if (!currentNodeType.contains("-list"))
+               index -= 3; 
+           else
+               index -= 2; // no plural in this case               
+               }
+       if (depNodeType != null) 
+               returnHash.putAll(depNodeHash);
+           
+               return returnHash;
+       }
+       
+       /**
+        * Parses the uri.
+        *
+        * @param allKeys the all keys
+        * @param keyList the key list
+        * @param uri the uri
+        * @param aaiExtMap the aai ext map
+        * @return the AAI resource
+        * @throws UnsupportedEncodingException the unsupported encoding exception
+        * @throws AAIException the AAI exception
+        */
+       public static AAIResource parseUri(HashMap<String, String> allKeys, LinkedHashMap<String, 
+                       LinkedHashMap<String,Object>> keyList, String uri, 
+                       AAIExtensionMap aaiExtMap) throws UnsupportedEncodingException, AAIException {          
+               
+               String[] ps = uri.split("/");
+               
+               String apiVersion = ps[0];
+               aaiExtMap.setApiVersion(apiVersion);
+               
+               AAIResources aaiResources = org.openecomp.aai.ingestModel.IngestModelMoxyOxm.aaiResourceContainer.get(apiVersion);
+               
+               String namespace = ps[1];
+               
+               aaiExtMap.setNamespace(namespace);
+               
+               // /vces/vce/{vnf-id}/port-groups/port-group/{port-group-id}/cvlan-tag-entry/cvlan-tag/{cvlan-tag}
+               
+               // FullName -> /Vces/Vce/PortGroups/PortGroup/CvlanTagEntry/CvlanTag <- 
+
+               String fullResourceName = "/" + CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, namespace);
+               AAIResources theseResources = new AAIResources();
+               
+               StringBuffer thisUri = new StringBuffer();
+               
+               // the URI config option in the props file has a trailing slash
+               thisUri.append("/" + namespace);
+                               
+               boolean firstNode = true;
+               
+               AAIResource lastResource = null;
+               
+               for (int i = 2; i < ps.length; i++) { 
+                       
+                       AAIResource aaiRes;
+                       StringBuffer tmpResourceName = new StringBuffer();
+                               
+                       String p = ps[i];
+                       String seg =ps[i];
+                                               
+                       thisUri.append("/" + seg);
+                       
+                       tmpResourceName.append(fullResourceName);
+                       
+                       if (seg.equals("cvlan-tag")) {
+                               seg = "cvlan-tag-entry";
+                       }
+                       tmpResourceName.append("/" + CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, seg));
+                       
+                       String tmpResource = tmpResourceName.toString();
+                       
+                       if (aaiResources.getAaiResources().containsKey(tmpResource)) {
+                               aaiRes = aaiResources.getAaiResources().get(tmpResource);
+                               lastResource = aaiRes;
+                               theseResources.getAaiResources().put(tmpResource, aaiRes);
+                               fullResourceName = tmpResource;
+                               if ("node".equals(aaiRes.getResourceType())) {
+                                       
+                                       if (firstNode == true) { 
+                                               aaiExtMap.setTopObjectFullResourceName(fullResourceName);
+                                               firstNode = false;
+                                       }
+                                                       
+                                       // get the keys, which will be in order and the next path segment(s)
+                                       AAIResourceKeys keys = aaiRes.getAaiResourceKeys();
+                                                                       
+                                       LinkedHashMap<String,Object> subKeyList = new LinkedHashMap<String,Object>();
+                                       
+                                       // there might not be another path segment
+                                       if ( (i + 1) < ps.length) { 
+
+                                               for (AAIResourceKey rk : keys.getAaiResourceKey()) {
+                                                       String p1 = ps[++i];
+                                                       String encodedKey = p1.toString();
+                                                       thisUri.append("/" + encodedKey);
+                                                       String decodedKey =  UriUtils.decode(p1.toString(), "UTF-8");
+                                                       subKeyList.put(rk.getKeyName(), decodedKey);
+                                               }
+                                               keyList.put(tmpResource, subKeyList);
+                                               // this is the key
+                                               allKeys.put(tmpResource, thisUri.toString());
+                                       }
+                               } else { // examples sit directly under the container level, should probably be query params!!!
+                                       if ( (i + 1) < ps.length) { 
+                                               String p1 = ps[i+1];
+                                               if (p1.toString().equals("example") || p1.toString().equals("singletonExample")) { 
+                                                       LinkedHashMap<String,Object> subKeyList = new LinkedHashMap<String,Object>();
+                                                       subKeyList.put("container|example", p1.toString());
+                                                       keyList.put(tmpResource, subKeyList);
+                                               }
+                                       }
+                               }
+                       } else {
+                               if (p.equals("relationship-list")) { 
+                                       LinkedHashMap<String,Object> subKeyList = new LinkedHashMap<String,Object>();
+                                       subKeyList.put("container|relationship", p.toString());
+                                       keyList.put(tmpResource, subKeyList);
+                               } else if ( p.toString().length() > 0 && !p.toString().equals("example") && !p.toString().equals("singletonExample") 
+                                               && !p.toString().equals("relationship") ) {
+                                       // this means the URL will break the model, so we bail
+                                       throw new AAIException("AAI_3001", "bad path");
+                               }
+                       }
+               }
+               aaiExtMap.setUri(AAIConfig.get("aai.global.callback.url")  + apiVersion + thisUri.toString());
+               aaiExtMap.setNotificationUri(AAIConfig.get("aai.global.callback.url") + AAIConfig.get("aai.notification.current.version") + thisUri.toString());
+               aaiExtMap.setFullResourceName(fullResourceName);
+               return lastResource;
+       }
+
+}
+
diff --git a/aai-traversal/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java b/aai-traversal/src/main/java/org/openecomp/aai/util/StoreNotificationEvent.java
new file mode 100644 (file)
index 0000000..996abba
--- /dev/null
@@ -0,0 +1,358 @@
+/*-
+ * ============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.util;
+
+import java.io.StringWriter;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.xml.bind.Marshaller;
+
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import org.openecomp.aai.dmaap.AAIDmaapEventJMSProducer;
+import org.openecomp.aai.domain.notificationEvent.NotificationEvent;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.exceptions.AAIUnknownObjectException;
+
+public class StoreNotificationEvent {
+
+       private AAIDmaapEventJMSProducer messageProducer;
+       private String fromAppId = "";
+       private String transId = "";
+
+       /**
+        * Instantiates a new store notification event.
+        */
+       public StoreNotificationEvent() {
+               this.messageProducer = new AAIDmaapEventJMSProducer();
+               Message inMessage = PhaseInterceptorChain.getCurrentMessage().getExchange().getInMessage();
+               Map<String, List<String>> headersList = CastUtils.cast((Map<?, ?>) inMessage.get(Message.PROTOCOL_HEADERS));
+               if (headersList != null) {
+                       List<String> xt = headersList.get("X-TransactionId");
+                       if (xt != null) {
+                               for (String transIdValue : xt) {
+                                       transId = transIdValue;
+                               }
+                       }
+                       List<String> fa = headersList.get("X-FromAppId");
+                       if (fa != null) {
+                               for (String fromAppIdValue : fa) {
+
+                                       fromAppId = fromAppIdValue;
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Store event.
+        *
+        * @param eh
+        *            the eh
+        * @param obj
+        *            the obj
+        * @throws AAIException
+        *             the AAI exception
+        */
+       public void storeEvent(NotificationEvent.EventHeader eh, Object obj) throws AAIException {
+
+               if (obj == null) {
+                       throw new AAIException("AAI_7350");
+               }
+
+               org.openecomp.aai.domain.notificationEvent.ObjectFactory factory = new org.openecomp.aai.domain.notificationEvent.ObjectFactory();
+
+               org.openecomp.aai.domain.notificationEvent.NotificationEvent ne = factory.createNotificationEvent();
+
+               if (eh.getId() == null) {
+                       eh.setId(genDate2() + "-" + UUID.randomUUID().toString());
+               }
+               if (eh.getTimestamp() == null) {
+                       eh.setTimestamp(genDate());
+               }
+
+               // there's no default, but i think we want to put this in hbase?
+
+               if (eh.getEntityLink() == null) {
+                       eh.setEntityLink("UNK");
+               }
+
+               if (eh.getAction() == null) {
+                       eh.setAction("UNK");
+               }
+
+               if (eh.getEventType() == null) {
+                       eh.setEventType(AAIConfig.get("aai.notificationEvent.default.eventType", "UNK"));
+               }
+
+               if (eh.getDomain() == null) {
+                       eh.setDomain(AAIConfig.get("aai.notificationEvent.default.domain", "UNK"));
+               }
+
+               if (eh.getSourceName() == null) {
+                       eh.setSourceName(AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK"));
+               }
+
+               if (eh.getSequenceNumber() == null) {
+                       eh.setSequenceNumber(AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK"));
+               }
+
+               if (eh.getSeverity() == null) {
+                       eh.setSeverity(AAIConfig.get("aai.notificationEvent.default.severity", "UNK"));
+               }
+
+               if (eh.getVersion() == null) {
+                       eh.setVersion(AAIConfig.get("aai.notificationEvent.default.version", "UNK"));
+               }
+
+               ne.setCambriaPartition(AAIConstants.UEB_PUB_PARTITION_AAI);
+               ne.setEventHeader(eh);
+               ne.setEntity(obj);
+
+               try {
+                       PojoUtils pu = new PojoUtils();
+                       String entityJson = pu.getJsonFromObject(ne);
+                       sendToDmaapJmsQueue(entityJson);
+               } catch (Exception e) {
+                       throw new AAIException("AAI_7350", e);
+               }
+       }
+
+       /**
+        * Store dynamic event.
+        *
+        * @param notificationJaxbContext
+        *            the notification jaxb context
+        * @param notificationVersion
+        *            the notification version
+        * @param eventHeader
+        *            the event header
+        * @param obj
+        *            the obj
+        * @throws AAIException
+        *             the AAI exception
+        */
+       public void storeDynamicEvent(DynamicJAXBContext notificationJaxbContext, String notificationVersion, DynamicEntity eventHeader, DynamicEntity obj) throws AAIException {
+
+               if (obj == null) {
+                       throw new AAIException("AAI_7350");
+               }
+
+               DynamicEntity notificationEvent = notificationJaxbContext.getDynamicType("inventory.aai.inventory.org." + notificationVersion + ".NotificationEvent").newDynamicEntity();
+
+               if (eventHeader.get("id") == null) {
+                       eventHeader.set("id", genDate2() + "-" + UUID.randomUUID().toString());
+               }
+               
+               if (eventHeader.get("timestamp") == null) {
+                       eventHeader.set("timestamp", genDate());
+               }
+
+               if (eventHeader.get("entityLink") == null) {
+                       eventHeader.set("entityLink", "UNK");
+               }
+
+               if (eventHeader.get("action") == null) {
+                       eventHeader.set("action", "UNK");
+               }
+
+               if (eventHeader.get("eventType") == null) {
+                       eventHeader.set("eventType", AAIConfig.get("aai.notificationEvent.default.eventType", "UNK"));
+               }
+
+               if (eventHeader.get("domain") == null) {
+                       eventHeader.set("domain", AAIConfig.get("aai.notificationEvent.default.domain", "UNK"));
+               }
+
+               if (eventHeader.get("sourceName") == null) {
+                       eventHeader.set("sourceName", AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK"));
+               }
+
+               if (eventHeader.get("sequenceNumber") == null) {
+                       eventHeader.set("sequenceNumber", AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK"));
+               }
+
+               if (eventHeader.get("severity") == null) {
+                       eventHeader.set("severity", AAIConfig.get("aai.notificationEvent.default.severity", "UNK"));
+               }
+
+               if (eventHeader.get("version") == null) {
+                       eventHeader.set("version", AAIConfig.get("aai.notificationEvent.default.version", "UNK"));
+               }
+
+               if (notificationEvent.get("cambriaPartition") == null) {
+                       notificationEvent.set("cambriaPartition", AAIConstants.UEB_PUB_PARTITION_AAI);
+               }
+
+               notificationEvent.set("eventHeader", eventHeader);
+               notificationEvent.set("entity", obj);
+
+               try {
+                       StringWriter result = new StringWriter();
+                       
+                       Marshaller marshaller = notificationJaxbContext.createMarshaller();
+                       marshaller.setProperty(org.eclipse.persistence.jaxb.MarshallerProperties.MEDIA_TYPE, "application/json");
+                       marshaller.setProperty(org.eclipse.persistence.jaxb.MarshallerProperties.JSON_INCLUDE_ROOT, false);
+                       marshaller.setProperty(org.eclipse.persistence.jaxb.MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, false);
+                       marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
+                       marshaller.marshal(notificationEvent, result);
+                       
+                       this.sendToDmaapJmsQueue(result.toString());
+
+               } catch (Exception e) {
+                       throw new AAIException("AAI_7350", e);
+               }
+       }
+
+       public void storeEvent(Loader loader, Introspector eventHeader, Introspector obj) throws AAIException {
+               if (obj == null) {
+                       throw new AAIException("AAI_7350");
+               }
+
+               try {
+                       final Introspector notificationEvent = loader.introspectorFromName("notification-event");
+
+                       if (eventHeader.getValue("id") == null) {
+                               eventHeader.setValue("id", genDate2() + "-" + UUID.randomUUID().toString());
+                       }
+
+                       if (eventHeader.getValue("timestamp") == null) {
+                               eventHeader.setValue("timestamp", genDate());
+                       }
+
+                       if (eventHeader.getValue("entity-link") == null) {
+                               eventHeader.setValue("entity-link", "UNK");
+                       }
+
+                       if (eventHeader.getValue("action") == null) {
+                               eventHeader.setValue("action", "UNK");
+                       }
+
+                       if (eventHeader.getValue("event-type") == null) {
+                               eventHeader.setValue("event-type", AAIConfig.get("aai.notificationEvent.default.eventType", "UNK"));
+                       }
+
+                       if (eventHeader.getValue("domain") == null) {
+                               eventHeader.setValue("domain", AAIConfig.get("aai.notificationEvent.default.domain", "UNK"));
+                       }
+
+                       if (eventHeader.getValue("source-name") == null) {
+                               eventHeader.setValue("source-name", AAIConfig.get("aai.notificationEvent.default.sourceName", "UNK"));
+                       }
+
+                       if (eventHeader.getValue("sequence-number") == null) {
+                               eventHeader.setValue("sequence-number", AAIConfig.get("aai.notificationEvent.default.sequenceNumber", "UNK"));
+                       }
+
+                       if (eventHeader.getValue("severity") == null) {
+                               eventHeader.setValue("severity", AAIConfig.get("aai.notificationEvent.default.severity", "UNK"));
+                       }
+
+                       if (eventHeader.getValue("version") == null) {
+                               eventHeader.setValue("version", AAIConfig.get("aai.notificationEvent.default.version", "UNK"));
+                       }
+
+                       if (notificationEvent.getValue("cambria-partition") == null) {
+                               notificationEvent.setValue("cambria-partition", AAIConstants.UEB_PUB_PARTITION_AAI);
+                       }
+
+                       notificationEvent.setValue("event-header", eventHeader.getUnderlyingObject());
+                       notificationEvent.setValue("entity", obj.getUnderlyingObject());
+
+                       String entityJson = notificationEvent.marshal(false);
+                       sendToDmaapJmsQueue(entityJson);
+               } catch (JSONException e) {
+                       throw new AAIException("AAI_7350", e);
+               } catch (AAIUnknownObjectException e) {
+                       throw new AAIException("AAI_7350", e);
+               }
+       }
+
+       private void sendToDmaapJmsQueue(String entityString) throws JSONException {
+               
+               JSONObject entityJsonObject = new JSONObject(entityString);
+               
+               JSONObject entityJsonObjectUpdated = new JSONObject();
+               JSONObject finalJson = new JSONObject();
+
+               JSONObject entityHeader = entityJsonObject.getJSONObject("event-header");
+               String cambriaPartition = entityJsonObject.getString("cambria.partition");
+
+               entityJsonObject.remove("event-header");
+               entityJsonObject.remove("cambria.partition");
+
+               entityJsonObjectUpdated.put("event-header", entityHeader);
+               entityJsonObjectUpdated.put("cambria.partition", cambriaPartition);
+               
+               Iterator<String> iter = entityJsonObject.keys();
+               JSONObject entity = new JSONObject();
+               if (iter.hasNext()) {
+                       entity = entityJsonObject.getJSONObject(iter.next());
+               }
+               
+               entityJsonObjectUpdated.put("entity", entity);
+
+               finalJson.put("event-topic", "AAI-EVENT");
+               finalJson.put("transId", transId);
+               finalJson.put("fromAppId", fromAppId);
+               finalJson.put("fullId", "");
+               finalJson.put("aaiEventPayload", entityJsonObjectUpdated);
+
+               messageProducer.sendMessageToDefaultDestination(finalJson);
+       }
+
+       /**
+        * Gen date.
+        *
+        * @return the string
+        */
+       public static String genDate() {
+               Date date = new Date();
+               DateFormat formatter = new SimpleDateFormat("YYYYMMdd-HH:mm:ss:SSS");
+               return formatter.format(date);
+       }
+
+       /**
+        * Gen date 2.
+        *
+        * @return the string
+        */
+       public static String genDate2() {
+               Date date = new Date();
+               DateFormat formatter = new SimpleDateFormat("YYYYMMddHHmmss");
+               return formatter.format(date);
+       }
+
+}
diff --git a/aai-traversal/src/main/resources/docker/Dockerfile b/aai-traversal/src/main/resources/docker/Dockerfile
new file mode 100644 (file)
index 0000000..66cf412
--- /dev/null
@@ -0,0 +1,85 @@
+FROM ubuntu:14.04
+
+ENV DEBIAN_FRONTEND noninteractive
+
+ENV HTTP_PROXY  ${HTTP_PROXY}
+ENV HTTPS_PROXY ${HTTP_PROXY}
+ENV https_proxy ${HTTP_PROXY}
+ENV http_proxy  ${HTTP_PROXY}
+
+# Setup JAVA_HOME, this is useful for docker commandline
+ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
+
+# Install all the application requirements such as curl ksh and git
+# Also install the chef and then remove it in one RUN command
+# Because the docker files work like git commits and each command is committed
+# So removing the chef in a different command will still have its in its build image
+# Its good to be optimizing and removing any files that are not needed for docker images
+# for the best possible performance out of your image
+
+RUN if [ ! -z ${HTTP_PROXY} ]; then echo "Acquire::http::proxy  \"${HTTP_PROXY}\";" >> /etc/apt/apt.conf; fi && \
+    if [ ! -z ${HTTP_PROXY} ]; then echo "Acquire::https::proxy \"${HTTP_PROXY}\";" >> /etc/apt/apt.conf; fi && \
+    apt-get update && \
+    apt-get install -y software-properties-common && \
+    apt-get install --reinstall ca-certificates && \
+    sudo -E add-apt-repository ppa:openjdk-r/ppa && \
+    apt-get update && \
+    apt-get -qq install -y openjdk-8-jre-headless git curl ksh && \
+    curl -k -LO  https://packages.chef.io/stable/ubuntu/14.04/chefdk_0.17.17-1_amd64.deb || \
+    curl --tlsv1 -LO https://packages.chef.io/stable/ubuntu/14.04/chefdk_0.17.17-1_amd64.deb && \
+    dpkg -i chefdk_0.17.17-1_amd64.deb && \
+    rm chefdk_0.17.17-1_amd64.deb && \
+    rm -rf /var/lib/apt/lists/*
+
+# Add the proper files into the docker image from your build
+ADD ./opt/app /opt/app
+ADD ./commonLibs/ /opt/app/commonLibs/
+ADD init-chef.sh /init-chef.sh
+ADD docker-entrypoint.sh /docker-entrypoint.sh
+ADD aai.sh /etc/profile.d/aai.sh
+
+# Expose the ports for outside linux to use
+# 8446 is the important one to be used
+
+EXPOSE 8446
+
+# Create the /var/chef if it doesn't exist
+WORKDIR /var/chef
+
+# Create the directory structure of aai application resembling the development server
+# hard-coding path to match ajsc version
+
+RUN chmod 755 /init-chef.sh /docker-entrypoint.sh && chmod 644 /etc/profile.d/aai.sh && \
+    mkdir /opt/aaihome && \
+    useradd -r -ms /bin/bash -d /opt/aaihome/aaiadmin aaiadmin && \
+    mkdir -p /opt/app/${project.artifactId}  && \
+    chown aaiadmin:aaiadmin /opt/app/${project.artifactId} && \
+    chown -R aaiadmin:aaiadmin /opt/app/${project.artifactId} && \
+    mkdir -p /opt/aai/logroot && \
+    chown -R aaiadmin:aaiadmin /opt/aai/logroot && \
+    ln -s /opt/app/${project.artifactId}/bin scripts && \
+    mkdir -p /opt/app/${project.artifactId}/extApps && chown -R aaiadmin:aaiadmin /opt/app/${project.artifactId}/extApps && \
+    find /opt/app/${project.artifactId}/bin -name "*.sh" -exec chmod 755 {} + && \
+    chown aaiadmin:aaiadmin /docker-entrypoint.sh && \
+    chown -R aaiadmin:aaiadmin /var/chef && \
+    mkdir -p /opt/aai/logroot/AAI-GQ && \
+    chown aaiadmin:aaiadmin /opt/aai/logroot/AAI-GQ && \
+    ln -s /opt/aai/logroot/AAI-GQ /opt/app/${project.artifactId}/logs && \
+    chown -R aaiadmin:aaiadmin /opt/app/${project.artifactId}/logs
+
+VOLUME /opt/aai/logroot/AAI-GQ
+
+WORKDIR /
+
+USER aaiadmin
+
+# When the container is started this is the entrypoint script
+# that docker will run. Make sure this script doesn't end abruptly
+# If you want the container running even if the main application stops
+# You can run a ever lasting process like tail -f /dev/null
+# Or something like that at the end of the docker-entrypoint script
+# So if the main application you are planning on running fails
+# the docker container keeps on running forever
+
+ENTRYPOINT ./docker-entrypoint.sh
+
diff --git a/aai-traversal/src/main/resources/docker/aai.sh b/aai-traversal/src/main/resources/docker/aai.sh
new file mode 100644 (file)
index 0000000..741076f
--- /dev/null
@@ -0,0 +1,42 @@
+###
+# ============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=========================================================
+###
+
+PROJECT_HOME=/opt/app/aai-traversal
+export PROJECT_HOME
+
+JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
+export JAVA_HOME
+
+AAIENV=dev
+export AAIENV
+
+PATH=/usr/lib/jvm/java-8-openjdk-amd64:$PATH
+
+PROJECT_OWNER=aaiadmin
+PROJECT_GROUP=aaiadmin
+PROJECT_UNIXHOMEROOT=/opt/aaihome
+export PROJECT_OWNER PROJECT_GROUP PROJECT_UNIXHOMEROOT
+umask 0022
+
+export idns_api_url=
+export idnscred=
+export idnstenant=
+
+
diff --git a/aai-traversal/src/main/resources/docker/commonLibs/README b/aai-traversal/src/main/resources/docker/commonLibs/README
new file mode 100644 (file)
index 0000000..00e36c0
--- /dev/null
@@ -0,0 +1 @@
+// this file's presence ensures commonLibs folder is present when image is created
\ No newline at end of file
diff --git a/aai-traversal/src/main/resources/docker/docker-entrypoint.sh b/aai-traversal/src/main/resources/docker/docker-entrypoint.sh
new file mode 100644 (file)
index 0000000..d776343
--- /dev/null
@@ -0,0 +1,34 @@
+###
+# ============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=========================================================
+###
+
+cd /opt/app/aai-traversal;
+
+TITAN_CACHED="/opt/app/aai-traversal/bundleconfig/etc/appprops/titan-cached.properties";
+TITAN_REALTIME="/opt/app/aai-traversal/bundleconfig/etc/appprops/titan-realtime.properties";
+SERVER_HOST=${SERVER_HOST:-localhost};
+SERVER_TABLE=${SERVER_TABLE:-aaigraph-dev02};
+
+sed -i 's/^storage.backend=inmemory/storage.backend=hbase/g' $TITAN_CACHED $TITAN_REALTIME;
+sed -i "s/^storage.hostname=.*$/storage.hostname=${SERVER_HOST}/g" $TITAN_CACHED $TITAN_REALTIME;
+sed -i "s/^storage.hbase.table=.*$/storage.hbase.table=${SERVER_TABLE}/g" $TITAN_CACHED $TITAN_REALTIME;
+
+/opt/app/aai-traversal/bin/createDBSchema.sh;
+
+java -cp ${CLASSPATH}:/opt/app/commonLibs/*:/opt/app/aai-traversal/etc:/opt/app/aai-traversal/lib/*:/opt/app/aai-traversal/extJars/logback-access-1.1.7.jar:/opt/app/aai-traversal/extJars/logback-core-1.1.7.jar:/opt/app/aai-traversal/extJars/aai-core-${AAI_CORE_VERSION}.jar -server -XX:NewSize=512m -XX:MaxNewSize=512m -XX:SurvivorRatio=8 -XX:+DisableExplicitGC -verbose:gc -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:-UseBiasedLocking -XX:ParallelGCThreads=4 -XX:LargePageSizeInBytes=128m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Dsun.net.inetaddr.ttl=180 -XX:+HeapDumpOnOutOfMemoryError -Dhttps.protocols=TLSv1.1,TLSv1.2 -DSOACLOUD_SERVICE_VERSION=1.0.1 -DAJSC_HOME=/opt/app/aai-traversal/ -DAJSC_CONF_HOME=/opt/app/aai-traversal/bundleconfig -DAJSC_SHARED_CONFIG=/opt/app/aai-traversal/bundleconfig -DAFT_HOME=/opt/app/aai-traversal -DAAI_CORE_VERSION=${AAI_CORE_VERSION} -Daai-core.version=${AAI_CORE_VERSION} -Dlogback.configurationFile=/opt/app/aai-traversal/bundleconfig/etc/logback.xml -Xloggc:/opt/app/aai-traversal/logs/ajsc-jetty/gc/graph-query_gc.log com.att.ajsc.runner.Runner context=/ port=8086 sslport=8446
diff --git a/aai-traversal/src/main/resources/docker/init-chef.sh b/aai-traversal/src/main/resources/docker/init-chef.sh
new file mode 100644 (file)
index 0000000..112b0b3
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+###
+# ============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=========================================================
+###
+
+##############################################################################
+#       Script to initialize the chef-repo branch and.chef
+#
+##############################################################################
+
+#echo "AAI_CHEF_ENV=${AAI_CHEF_ENV}" >> /etc/environment
+#echo "AAI_CHEF_LOC=${AAI_CHEF_LOC}" >> /etc/environment
+#touch /root/.bash_profile
+chef-solo -c /var/chef/aai-data/chef-config/dev/.knife/solo.rb -j /var/chef/aai-config/cookbooks/runlist-app-server.json -E ${AAI_CHEF_ENV}
+
diff --git a/aai-traversal/src/main/resources/schema/UebEventLogEntry.xsd b/aai-traversal/src/main/resources/schema/UebEventLogEntry.xsd
new file mode 100644 (file)
index 0000000..c679fd2
--- /dev/null
@@ -0,0 +1,20 @@
+<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:complexType name="UebEventLogEntry">
+          <xs:sequence>
+                 <xs:element type="xs:string" name="transactionLogEntryId"/>
+             <xs:element type="xs:string" name="notificationId"/>
+             <xs:element type="xs:string" name="topic"/>
+             <xs:element type="xs:string" name="action"/>
+             <xs:element minOccurs="0" type="xs:string" name="entityLink"/>
+             <xs:element type="xs:string" name="payload"/>
+             <xs:element type="xs:string" name="status"/>
+             <xs:element minOccurs="0" type="xs:string" name="owner"/>
+             <xs:element type="xs:long" name="lastUpdateTimestamp"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="UebEventLogEntries">
+          <xs:sequence>
+             <xs:element minOccurs="0" maxOccurs="unbounded" name="UebEventLogEntries" type="UebEventLogEntry"/>
+       </xs:sequence>
+     </xs:complexType>
+</xs:schema>
diff --git a/aai-traversal/src/main/runtime/context/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.context b/aai-traversal/src/main/runtime/context/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.context
new file mode 100644 (file)
index 0000000..8514196
--- /dev/null
@@ -0,0 +1 @@
+{"context":{"contextClass":"ajsc.Context","contextId":"__module_ajsc_namespace_name__:__module_ajsc_namespace_version__","contextName":"__module_ajsc_namespace_name__","contextVersion":"__module_ajsc_namespace_version__","description":"__module_ajsc_namespace_name__ Context"}}
\ No newline at end of file
diff --git a/aai-traversal/src/main/runtime/context/default#0.context b/aai-traversal/src/main/runtime/context/default#0.context
new file mode 100644 (file)
index 0000000..d1b5ab4
--- /dev/null
@@ -0,0 +1 @@
+{"context":{"contextClass":"ajsc.Context","contextId":"default:0","contextName":"default","contextVersion":"0","description":"Default Context"}}
\ No newline at end of file
diff --git a/aai-traversal/src/main/runtime/deploymentPackage/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.json b/aai-traversal/src/main/runtime/deploymentPackage/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.json
new file mode 100644 (file)
index 0000000..d0954cf
--- /dev/null
@@ -0,0 +1 @@
+{"deploymentPackage":{"Class":"ajsc.DeploymentPackage","Id":"__module.ajsc.namespace.name__:__module_ajsc_namespace_version__","namespace":"__module_ajsc_namespace_name__","namespaceVersion":"__module_ajsc_namespace_version__","description":"__module_ajsc_namespace_name__ __module_ajsc_namespace_version__ - default description","userId":"ajsc"}}
\ No newline at end of file
diff --git a/aai-traversal/src/main/runtime/shiroRole/ajscadmin.json b/aai-traversal/src/main/runtime/shiroRole/ajscadmin.json
new file mode 100644 (file)
index 0000000..f5e981e
--- /dev/null
@@ -0,0 +1 @@
+{"shiroRoleClass":"ajsc.auth.ShiroRole","shiroRoleId":"ajscadmin","name":"ajscadmin","permissions":"[ajscadmin:*, ajsc:*]"}
\ No newline at end of file
diff --git a/aai-traversal/src/main/runtime/shiroRole/contextadmin#__module.ajsc.namespace.name__.json b/aai-traversal/src/main/runtime/shiroRole/contextadmin#__module.ajsc.namespace.name__.json
new file mode 100644 (file)
index 0000000..2dae9f5
--- /dev/null
@@ -0,0 +1 @@
+{"shiroRoleClass":"ajsc.auth.ShiroRole","shiroRoleId":"contextadmin:__module_ajsc_namespace_name__","name":"contextadmin:__module_ajsc_namespace_name__","permissions":"[]"}
\ No newline at end of file
diff --git a/aai-traversal/src/main/runtime/shiroRole/contextadmin#default.json b/aai-traversal/src/main/runtime/shiroRole/contextadmin#default.json
new file mode 100644 (file)
index 0000000..5de814e
--- /dev/null
@@ -0,0 +1 @@
+{"shiroRoleClass":"ajsc.auth.ShiroRole","shiroRoleId":"contextadmin:default","name":"contextadmin:default","permissions":"[]"}
\ No newline at end of file
diff --git a/aai-traversal/src/main/runtime/shiroUser/ajsc.json b/aai-traversal/src/main/runtime/shiroUser/ajsc.json
new file mode 100644 (file)
index 0000000..f4c7855
--- /dev/null
@@ -0,0 +1 @@
+{"shiroUserClass":"ajsc.auth.ShiroUser","shiroUserId":"ajsc","passwordHash":"9471697417008c880720ba54c6038791ad7e98f3b88136fe34f4d31a462dd27a","permissions":"[*:*]","username":"ajsc"}
\ No newline at end of file
diff --git a/aai-traversal/src/main/runtime/shiroUserRole/ajsc#ajscadmin.json b/aai-traversal/src/main/runtime/shiroUserRole/ajsc#ajscadmin.json
new file mode 100644 (file)
index 0000000..cb8d483
--- /dev/null
@@ -0,0 +1 @@
+{"shiroUserRoleClass":"ajsc.auth.ShiroUserRole","shiroUserRoleId":"ajsc:ajscadmin","roleId":"ajscadmin","userId":"ajsc"}
\ No newline at end of file
diff --git a/aai-traversal/src/main/runtime/shiroUserRole/ajsc#contextadmin#__module.ajsc.namespace.name__.json b/aai-traversal/src/main/runtime/shiroUserRole/ajsc#contextadmin#__module.ajsc.namespace.name__.json
new file mode 100644 (file)
index 0000000..95d2361
--- /dev/null
@@ -0,0 +1 @@
+{"shiroUserRoleClass":"ajsc.auth.ShiroUserRole","shiroUserRoleId":"ajsc:contextadmin:__module_ajsc_namespace_name__","roleId":"contextadmin:__module_ajsc_namespace_name__","userId":"ajsc"}
\ No newline at end of file
diff --git a/aai-traversal/src/main/runtime/shiroUserRole/ajsc#contextadmin#default.json b/aai-traversal/src/main/runtime/shiroUserRole/ajsc#contextadmin#default.json
new file mode 100644 (file)
index 0000000..2bd5063
--- /dev/null
@@ -0,0 +1 @@
+{"shiroUserRoleClass":"ajsc.auth.ShiroUserRole","shiroUserRoleId":"ajsc:contextadmin:default","roleId":"contextadmin:default","userId":"ajsc"}
\ No newline at end of file
diff --git a/aai-traversal/src/main/scripts/getTool.sh b/aai-traversal/src/main/scripts/getTool.sh
new file mode 100644 (file)
index 0000000..8cdc7d1
--- /dev/null
@@ -0,0 +1,88 @@
+#!/bin/ksh
+
+###
+# ============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=========================================================
+###
+
+#
+# The script is called with a resource.
+# It invokes a GET on the resource using curl
+# Uses aaiconfig.properties for authorization type and url.
+
+# remove leading slash when present
+RESOURCE=`echo $1 | sed "s,^/,,"`
+if [ -z $RESOURCE ]; then
+        echo "resource parameter is missing"
+        echo "usage: $0 resource file [expected-failure-codes]"
+        exit 1
+fi
+echo `date` "   Starting $0 for resource $RESOURCE"
+
+XFROMAPPID="AAI-TOOLS"
+XTRANSID=`uuidgen`
+
+userid=$( id | cut -f2 -d"(" | cut -f1 -d")" )
+if [ "${userid}" != "aaiadmin" ]; then
+    echo "You must be aaiadmin to run $0. The id used $userid."
+    exit 1
+fi
+
+. /etc/profile.d/aai.sh
+PROJECT_HOME=/opt/app/aai-graph-query
+prop_file=$PROJECT_HOME/bundleconfig/etc/appprops/aaiconfig.properties
+log_dir=$PROJECT_HOME/logs/misc
+today=$(date +\%Y-\%m-\%d)
+
+MISSING_PROP=false
+RESTURL=`grep ^aai.server.url= $prop_file |cut -d'=' -f2 |tr -d "\015"`
+if [ -z $RESTURL ]; then
+        echo "Property [aai.server.url] not found in file $prop_file"
+        MISSING_PROP=true
+fi
+USEBASICAUTH=false
+BASICENABLE=`grep ^aai.tools.enableBasicAuth $prop_file |cut -d'=' -f2 |tr -d "\015"`
+if [ -z $BASICENABLE ]; then
+        USEBASICAUTH=false
+else
+        USEBASICAUTH=true
+        CURLUSER=`grep ^aai.tools.username $prop_file |cut -d'=' -f2 |tr -d "\015"`
+        if [ -z $CURLUSER ]; then
+                echo "Property [aai.tools.username] not found in file $prop_file"
+                MISSING_PROP=true
+        fi
+        CURLPASSWORD=`grep ^aai.tools.password $prop_file |cut -d'=' -f2 |tr -d "\015"`
+        if [ -z $CURLPASSWORD ]; then
+                echo "Property [aai.tools.password] not found in file $prop_file"
+                MISSING_PROP=true
+        fi
+fi
+
+if [ $MISSING_PROP = false ]; then
+        if [ $USEBASICAUTH = false ]; then
+                AUTHSTRING="--cert $PROJECT_HOME/bundleconfig/etc/auth/aaiClientPublicCert.pem --key $PROJECT_HOME/bundleconfig/etc/auth/aaiClientPrivateKey.pem"
+        else
+                AUTHSTRING="-u $CURLUSER:$CURLPASSWORD"
+        fi
+        curl --request GET -sL -k $AUTHSTRING -H "X-FromAppId: $XFROMAPPID" -H "X-TransactionId: $XTRANSID" -H "Accept: application/json" $RESTURL$RESOURCE
+        RC=$?;
+else
+        echo "usage: $0 resource"
+        RC=-1
+fi
+
+echo `date` "   Done $0, returning $RC"
+exit $RC
diff --git a/aai-traversal/src/main/scripts/install/instutils.sh b/aai-traversal/src/main/scripts/install/instutils.sh
new file mode 100644 (file)
index 0000000..a512606
--- /dev/null
@@ -0,0 +1,724 @@
+#!/bin/ksh
+
+###
+# ============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=========================================================
+###
+
+ECHO=${ECHO:-echo}
+
+q_flags="-qq -k$$"
+
+show_install=${PROJECT_HOME}/install/show_install
+
+############################################################################
+# checkgroup groupname gid
+# checks if group is already in /etc/group and if it has the right gid
+# if it's not there, it adds it
+# gid can be DC if you don't care
+############################################################################
+checkgroup () {
+       ecode=0
+       OFILE=/tmp/group.$$
+       getent group "$1" > $OFILE
+       if [ $? -eq 0 ]
+       then
+               CHECKGID=$( grep "^$1:" $OFILE | cut -f3 -d: 2>/dev/null )
+               CHECKGROUPPRESENT=$( grep "^$1:" $OFILE | cut -f1 -d: 2>/dev/null )
+               CHECKGROUP=$( grep ":$2:" $OFILE | cut -f1 -d: 2>/dev/null )
+       fi
+       if [ "${CHECKGID}" = "" -a "${CHECKGROUP}" = "" ]
+       then
+               ${ECHO} "Adding $1 group ..."
+               if [ "$2" = "DC" ]
+               then
+                       groupadd $1 
+               else
+                       groupadd -g $2 $1 
+               fi
+               if [ "$?" != "0" ]
+               then
+                       ${ECHO} "Cannot add group $1, continuing..."
+                       ecode=1
+               fi
+       else
+               if [ "${CHECKGROUPPRESENT}" = "$1" ]
+               then
+                       if [ "$2" != "DC" ]  
+                       then
+                               if [ "${CHECKGID}" != "$2" ]
+                               then
+                                       ${ECHO} "ERROR:  $1 group added but with wrong gid \"${CHECKGID}\"; should be $2"
+                                       ecode=1
+                               fi
+                               if [ "${CHECKGROUP}" != "$1" ]
+                               then
+                                       ${ECHO} "ERROR:  wrong group \"${CHECKGROUP}\" for gid $2, group should be $1"
+                                       ecode=1
+                               fi
+                       else
+                               ${ECHO} "$1 group has already been added"
+                       fi
+               fi
+       fi
+       rm -f $OFILE
+       return ${ecode}
+}
+
+############################################################################
+# checkuser username uid homedir shell group
+# checks if the username/uid/homedir/shell combo is already in /etc/passwd
+# if not, it adds it
+# if the login is there and the uid belongs to a different user, it errors
+# if the login is there and the shell is not correct, it errors
+# uid may be DC for don't care
+############################################################################
+checkuser () {
+       ecode=0
+       OFILE=/tmp/user.$$
+       getent passwd $1 > $OFILE
+       if [ $? -eq 0 ]
+       then    
+               CHECKUID=$( grep "^$1:" $OFILE | cut -f3 -d: 2>/dev/null )
+               CHECKLOGIN=$( grep ":x:$2:" $OFILE | cut -f1 -d: 2>/dev/null )
+               CHECKLOGINPRESENT=$( grep "^$1:" $OFILE | cut -f1 -d: 2>/dev/null )
+               CHECKSHELL=$( grep "^$1:" $OFILE | cut -f7 -d: 2>/dev/null )
+               CHECKHOME=$( grep "^$1:" $OFILE | cut -f6 -d: 2>/dev/null )
+       fi
+       
+       if [ ! -d $3 ]
+       then
+               mkdir -p $3
+               if [ "$?" != "0" ]
+               then
+                       ${ECHO} "mkdir -p $3 failed"
+                       ecode=1
+               fi
+               chmod -R 755 $3
+       fi
+       if [ "${CHECKUID}" = "" -a "${CHECKLOGIN}" = "" ]
+       then
+               ${ECHO} "Adding $1 login ..."
+               if [ "$2" = "DC" ]
+               then
+                       useradd -g $5 -d $3 -s $4 -c "$1 LOGIN" -m $1
+               else
+                       useradd -u $2 -g $5 -d $3 -s $4 -c "$1 LOGIN" -m $1
+               fi
+               if [ "$?" != "0" ]
+               then
+                       ${ECHO} "Cannot add $1 login, continuing..."
+                       ecode=1
+               fi
+       elif [ "${CHECKLOGINPRESENT}" = "$1" -a "$2" = "DC" -a "${CHECKSHELL}" = "$4" -a "${CHECKHOME}" = "$3" ]
+       then
+               ${ECHO} "The '$1' login has already been added to system with UID ${CHECKUID}."
+       
+       elif [ "${CHECKUID}" = "$2" -a "${CHECKLOGIN}" = "$1" -a "${CHECKSHELL}" = "$4" -a "${CHECKHOME}" = "$3" ]
+       then
+               ${ECHO} "The '$1' login has already been added to system."
+       else
+               if [ "$2" != "DC" -a "${CHECKUID}" != "$2" ]
+               then
+                       ${ECHO} "ERROR:  $1 login added but with wrong uid \"${CHECKUID}\"; should be $2"
+                       ecode=1
+               fi
+               if [ "$2" != "DC" -a "${CHECKLOGIN}" != "$1" ]
+               then
+                       ${ECHO} "ERROR:  wrong login \"${CHECKLOGIN}\" for uid $2, login should be $1"
+                       ecode=1
+               fi
+               if [ "${CHECKHOME}" != "$3" ]
+               then
+                       ${ECHO} "ERROR:  wrong home directory \"${CHECKHOME}\" for login $1, should be $3"
+                       ecode=1
+               fi
+               if [ "${CHECKSHELL}" != "$4" ]
+               then
+                       ${ECHO} "ERROR:  $1 login not set up with $4"
+                       ecode=1
+               fi
+       fi
+       rm -f $OFILE
+       return ${ecode}
+}
+
+############################################################################
+# checkhome username homedir action
+# if the user doesn't exist, it errors
+# checks if the username has homedir as its home directory
+# if not and action is null, it modifies it
+# if not and action is mod, it modifies it
+# if not and action is error, it errors
+############################################################################
+checkhome () {
+       ecode=0
+       OFILE=/tmp/user.$$
+       getent passwd $1 > $OFILE
+       if [ $? -eq 0 ]
+       then    
+               CHECKUID=$( grep "^$1:" $OFILE | cut -f3 -d: 2>/dev/null )
+               CHECKGID=$( grep "^$1:" $OFILE | cut -f4 -d: 2>/dev/null )
+               CHECKHOME=$( grep "^$1:" $OFILE | cut -f6 -d: 2>/dev/null )
+               
+               if [ "${CHECKHOME}" = "$2" ] 
+               then
+                       if [ ! -d $2 ]
+                       then
+                               mkdir -p $2
+                               if [ "$?" != "0" ]
+                               then
+                                       ${ECHO} "mkdir -p $2 failed"
+                                       ecode=1
+                               fi
+                               chown ${CHECKUID}:${CHECKGID} $2
+                               chmod -R 755 $2
+                       fi
+               else
+                       # modify the user to set the new home dir and move any current home dir to there
+                       usermod -d $2 -m $1
+                       if [ "$?" != "0" ]
+                       then
+                               ${ECHO} "usermod -d $2 -m $1 failed"
+                               ecode=1
+                       fi
+               fi
+       else
+               ${ECHO} "user $1 doesn't exist"
+               ecode=1
+       fi
+       
+       rm -f $OFILE
+       return ${ecode}
+}
+
+##################################################################
+#checkloginsforpwds checks /etc/shadow for logins without passwords
+# the first argument is a list of logins to check
+##################################################################
+checkloginsforpwds () {
+       for i in $1
+       do
+               CHECK_LOGIN=$( grep "^${i}:" /etc/shadow | grep "!!" )
+               if [ "${CHECK_LOGIN}" != "" ]
+               then
+                       NOPWD="${NOPWD} ${i}"
+               fi
+       done
+       
+       if [ "${NOPWD}" != "" ]
+       then
+          ${ECHO} ""
+          ${ECHO} "REMINDER:  The following logins must have a passwords assigned to them.\n"
+          ${ECHO} "##############################################################"
+          ${ECHO} "            ${NOPWD}        "
+          ${ECHO} "##############################################################"
+          ${ECHO} ""
+          ${ECHO} "           This must be done by executing the following command:"
+          ${ECHO} ""
+          ${ECHO} "           $ passwd <login>"
+          ${ECHO} ""
+          ${ECHO} "           After typing the \"passwd\" command you will be prompted for"
+          ${ECHO} "           the password for the login."          
+          ${ECHO} ""
+       fi
+}
+
+##################################################################
+# checkassignpasswords checks /etc/shadow for logins without passwords
+# and then asks the user to assign one
+# the first argument is a list of logins to check
+##################################################################
+checkassignpasswords () {
+       for i in $1
+       do
+               CHECK_LOGIN=$( grep "^${i}:" /etc/shadow | grep LK )
+               if [ "${CHECK_LOGIN}" != "" ]
+               then
+                       ${ECHO} "Please assign a password for the '${i}' login"
+                       passwd ${i}
+                       ${ECHO}
+               fi
+       done
+}
+
+############################################################################
+# copywithperms origfile destfile owner group perms [save suffix]
+# copies origfile to destfile, giving destfile ownership and permssions
+# from owner, group, and perms.  If the sixth argument is "save", the
+# original is saved in the same place with the seventh argument as the
+# suffix.  If the seventh arg is null, $$ is used
+############################################################################
+copywithperms () {
+       SAVE=0
+       ECODE=0
+       if [ "$6" = "save" -a -f "$2" ]
+       then
+               if [ "$7" = "" ]
+               then
+                       cp $2 $2.$$
+               else
+                       cp $2 $2.$7
+               fi
+       fi
+       if [ -f $1 ]
+       then
+               cp $1 $2
+               ECODE=$?
+               chown ${3}:${4} $2
+               chmod $5 $2
+       else
+               ${ECHO} "$1 is not a file.  No copy done!"
+       fi
+       return ${ECODE}
+}
+
+############################################################################
+# mkdirwithperms dirname owner group perms ifExist
+# makes directory dirname , giving dirname ownership and permssions
+# from owner, group, and perms.  
+# perms can be DC if you don't care
+# ifExist can be rm, error, dontcreate
+############################################################################
+mkdirwithperms () {
+       ECODE=0
+       if [ -f $1 ]
+       then
+               ECODE=1
+               ${ECHO} "$1 exists but is a file.  No mkdir done!"
+       elif [ -d $1 ]
+       then
+               if [ "$5" = "rm" ]
+               then
+                       rm -rf $1
+                       mkdir -p $1
+                       if [ "$?" != "0" ]
+                       then
+                               ${ECHO} "mkdir -p $1 failed"
+                               ECODE=1
+                       fi
+               elif [ "$5" = "error" ]
+               then
+                       ECODE=1
+                       ${ECHO} "$1 is a directory.  No mkdir done!"
+               elif [ "$5" != "dontcreate" ]
+               then
+                       mkdir -p $1
+                       if [ "$?" != "0" ]
+                       then
+                               ${ECHO} "mkdir -p $1 failed"
+                               ECODE=1
+                       fi
+               fi
+       else
+               mkdir -p $1
+               if [ "$?" != "0" ]
+               then
+                       ${ECHO} "mkdir -p $1 failed"
+                       ECODE=1
+               fi
+       fi
+       if [ "${ECODE}" = "0" ]
+       then
+               chown ${2}:${3} $1
+               if [ "$4" != "DC" ]
+               then
+                       chmod $4 $1
+               fi
+       fi
+       return ${ECODE}
+}
+
+
+############################################################################
+# chownwithperms owner group file mode
+# changes the ownership and mode for the specified file
+############################################################################
+chownwithperms () {
+       chown ${1}:${2} $3
+       chmod $4 $3
+}
+
+verifywhosrunning () {
+       userid=$( id | cut -f2 -d"(" | cut -f1 -d")" )
+       if [ "${userid}" != "$1" ]
+       then
+               ${ECHO} "You must be $1 to run $0"
+               exit 1
+       fi
+}
+
+replaceline() {
+
+       name=$1
+       value=$2
+       file=$3
+
+       if [ -z "${file}" ]
+       then
+               ${ECHO} "replaceline: ERROR: insufficient arguments: $1 $2" >&2
+               return 1
+       fi
+
+       if [ -n "$4" ]
+       then
+               ${ECHO} "replaceline: ERROR: too many arguments: $1 $2 $3 $4" >&2
+               return 1
+       fi
+
+       if [ -f ${file} ]
+       then
+               grep -v "^${name}=" ${file} > ${file}.$$
+               ${ECHO} "${name}=${value}" >> ${file}.$$
+               mv -f ${file}.$$ ${file}
+       else 
+               ${ECHO} "${name}=${value}" > ${file}
+       fi
+}
+
+replaceline_with_quotes() {
+
+       name=$1
+       value=$2
+       file=$3
+
+       if [ -z "${file}" ]
+       then
+               ${ECHO} "replaceline: ERROR: insufficient arguments: $1 $2" >&2
+               return 1
+       fi
+
+       if [ -n "$4" ]
+       then
+               ${ECHO} "replaceline: ERROR: too many arguments: $1 $2 $3 $4" >&2
+               return 1
+       fi
+
+       if [ -f ${file} ]
+       then
+               grep -v "^${name}=" ${file} > ${file}.$$
+               ${ECHO} "${name}=\"${value}\"" >> ${file}.$$
+               mv -f ${file}.$$ ${file}
+       else 
+               ${ECHO} "${name}=\"${value}\"" > ${file}
+       fi
+}
+
+# this deleteline will not actually delete the entry
+# but only delete the value leaving the name=
+# when siteconf.pl went from Boilerplate to Fillin,
+# we changed this because Fillin can handle null values.
+
+deleteline() {
+
+       name=$1
+       file=$2
+
+       if [ -z "${file}" ]
+       then
+               ${ECHO} "deleteline: ERROR: insufficient arguments" >&2
+               return 1
+       fi
+
+       if [ -f ${file} ]
+       then
+               cp ${file} ${file}.$$
+               lno=$( grep -n "^${name}=" ${file} | cut -d: -f1 )
+               if [ "${lno}" != "" ] 
+               then
+                       sed "${lno}d" ${file} > ${file}.$$
+               fi
+               ${ECHO} "${name}=" >> ${file}.$$
+               mv -f ${file}.$$ ${file}
+       else 
+               ${ECHO} "${name}=" > ${file}
+       fi
+}
+
+# dropline will drop the line from the file
+# unlike the deleteline function above
+
+dropline() {
+
+       name=$1
+       file=$2
+
+       if [ -z "${file}" ]
+       then
+               ${ECHO} "dropline: ERROR: insufficient arguments" >&2
+               return 1
+       fi
+
+       if [ -f ${file} ]
+       then
+               grep -v "^${name}=" ${file} > ${file}.$$
+               mv -f ${file}.$$ ${file}
+       fi
+}
+
+pause_install() {
+
+       if [ "${Pause}" =  "1" ]
+       then
+               if ${chkyn} -y "Continue with ${Itype}?"
+               then
+                       return 0
+               else
+                       ${ECHO} "${PNAME}: quitting" >&2
+                       exit 1
+               fi
+       fi
+}
+
+get_ITYPE() {
+       ITYPE=$( ${chkyn} -fer ${q_flags} -h\? ${ITYPE:+-D"${ITYPE}"} -H \
+"      If you are doing a fresh install, answer 'I' or answer 'U' for upgrade." \
+"Is this a fresh 'install' or 'upgrade' (I or U):${ITYPE:+ [${ITYPE}]}" \
+       '^[IU]$' \
+'*** ERROR *** Entry must be I or U.' )
+}
+
+
+###
+# Change an /etc/group entry to allow a give user to change group into it.
+# arg1 = comma-sep group list (e.g., sylantro,other)
+# arg2 = user
+###
+addUserToGroup()
+{
+       if [ -z "$1" -o -z "$2" ]
+       then
+               ${ECHO} "addUserToGroup failed, need two args, group and user"
+               return 1
+       else
+               usermod -G $1 $2
+       fi
+       return 0
+}
+
+################### BACKUP AND RESTORE METHODS ########################
+###################       VARIABLES          ##########################
+###################       VARIABLES          ##########################
+###################       VARIABLES          ##########################
+###################       VARIABLES          ##########################
+
+NO_FILE_INDICATOR="__NO_PREVIOUS_FILE__"
+SAVE_SUFFIX=${Project}save
+
+###################       SUBROUTINES        ##########################
+###################       SUBROUTINES        ##########################
+###################       SUBROUTINES        ##########################
+###################       SUBROUTINES        ##########################
+###################       SUBROUTINES        ##########################
+
+##############################################################################
+# Purpose:  make a backup copy of a file in such a way that the backup
+# won't be lost by re-running your script PLUS give you a predictable name
+# for the most recent back up to use when you roll back.
+#
+# Input:
+# - Arg1 = file to back up
+#
+# Requirement: 
+# - Remove $1.save before calling this function or else a copy won't be made.
+# - Make sure to set the value of env value TODAY to use as a suffix.
+#
+# Description:
+# Copy $1 to $1.${SAVE_SUFFIX}.${TODAY}, then link that to $1.save.
+#
+##############################################################################
+make_backup_copy ()
+{
+       if [ -z "${TODAY}" ]
+       then
+               ${ECHO} "make_backup_copy - TODAY variable is unset" >&2
+               return 1
+       fi
+
+       if [ -f $1.${SAVE_SUFFIX}.${TODAY} -a -h $1.save ]
+       then
+               ${ECHO} "Note: backup already exists for $1"
+       else
+               # if existing file doesn't exist, set up for later delete by rollback
+               if [ ! -f $1 -a ! -h $1 ]
+               then
+                       ${ECHO} ${NO_FILE_INDICATOR} > $1
+               fi
+               cp -p $1 $1.${SAVE_SUFFIX}.${TODAY}
+               ln -s $1.${SAVE_SUFFIX}.${TODAY} $1.save
+       fi
+}
+
+################################################################################
+# Purpose: Find the actual file that belongs to $1, which can be a symbolic 
+# link.
+# 
+# Input:
+# - Arg1 = path to file or link
+# - Arg2 = true if you want _SRCFILE to be null if no actual file is 
+#      found.  If Arg2 is NOT true, then _SRCFILE is set to Arg1.
+# 
+# Side Effect:
+# Sets value of _SRCFILE variable
+################################################################################
+find_source_file ()
+{
+       if [ -z "$1" ]
+       then
+               ${ECHO} "find_source_file - needs at least one argument" >&2
+               return 1
+       fi
+
+       ls -l $1 > /tmp/tls$$
+       cat /tmp/tls$$ | sed 's/  */    /g' |cut -f11 > /tmp/cuts$$
+       _SRCFILE=$( cat /tmp/cuts$$ )
+
+       if [ "$_SRCFILE" = "" ]
+       then
+               if [ "$2" != "true" ]
+               then
+                       _SRCFILE=$1
+               fi
+       fi
+       rm -f /tmp/tls$$ /tmp/cuts$$
+}
+
+#######################################################################
+# Purpose: Expands template file using data in COPT variable.
+# Diffs expanded template against existing file and installs if different.
+# If arg5 = true, sets _config_changes=1 so you know that changes were installed
+#
+# Makes its own backup copy using make_backup_copy.
+# Does install if different using install_if_different.
+#
+# Input:
+# Arg1 = template path without .tmpl extension
+# Arg2 = install path
+# Arg3 = owner and group (e.g., root:other)
+# Arg4 = permissions (e.g., 750)
+# Arg5 = true/false, if expanded file is different than installed .
+#              Set _config_changes to 1 if Arg5 is true.  Otherwise, don't touch 
+#              _config_changes
+# 
+# Requirement: set COPT to the value of the -c option to siteconf.pl
+#
+# Side Effect: sets _config_changes=1 if changes were installed
+#######################################################################
+install_from_template () 
+{
+       if [ -z "${COPT}" ]
+       then
+               ${ECHO} "install_from_template - COPT is unset" >&2
+               return 1
+       fi
+
+       TMPL=$( basename ${1} )
+       OFILE=/tmp/${TMPL}
+       if [ -f ${1}.tmpl ]
+       then
+
+               ${PROJECT_HOME}/bin/siteconf.pl -t ${1}.tmpl -c ${COPT} -o ${OFILE}
+               install_if_different ${OFILE} ${2} ${3} ${4} ${5}
+
+       else
+               ${ECHO} "install_from_template: ERROR: Missing ${TMPL}.tmpl" >&2
+       fi
+       rm -f ${OFILE}
+}
+
+
+#######################################################################
+# Purpose: Copies source to destination if the two are different.
+# If arg5 = true, sets _config_changes=1 so you know that changes were installed
+#
+# Makes its own backup copy using make_backup_copy.
+#
+# Input:
+# Arg1 = source path
+# Arg2 = install path
+# Arg3 = owner and group (e.g., root:other)
+# Arg4 = permissions (e.g., 750)
+# Arg5 = true/false, if expanded file is different than installed .
+#              Set _config_changes to 1 if Arg5 is true.  Otherwise, don't touch 
+#              _config_changes
+# 
+# Side Effect: sets _config_changes=1 if changes were installed
+#######################################################################
+install_if_different()
+{
+               # Take backup before changing.
+               # Only change if different.
+               if [ -f ${2} ]
+               then
+                       diff ${1} ${2} > /dev/null
+                       diffrc=$?
+                       if [ "${diffrc}" != "0" ]
+                       then
+                               ${ECHO} "Installing ${2}"
+                               make_backup_copy ${2}
+                               mv -f ${1} ${2}
+                               chown ${3} ${2}
+                               chmod ${4} ${2}
+                               if [ "${5}" = "true" ]
+                               then
+                                       _config_changes=1
+                               fi
+                       fi
+               else
+                       # creates backup containing ${NO_FILE_INDICATOR} for rollback removal
+                       make_backup_copy ${2}  
+                       mv -f ${1} ${2}
+                       chown ${3} ${2}
+                       chmod ${4} ${2}
+                       if [ "${5}" = "true" ]
+                       then
+                               _config_changes=1
+                       fi
+               fi
+}
+###################################################################
+# Purpose: rollback a file whose backup was made with make_backup_copy
+#
+# Input:
+# Arg1 is path of installed file. Subroutine will look for ${1}.save
+# Arg2 = true/false, if expanded file is different than installed, 
+#              set _config_changes to 1 if Arg2 is true.  Otherwise, don't touch 
+#              _config_changes
+#
+# Side Effect: sets _config_changes=1 if changes were rolled back
+###################################################################
+rollback_from_save ()
+{
+       if [ -f ${1}.save -o -h ${1}.save ]
+       then
+               find_source_file ${1}.save false
+               ${ECHO} "rollback_from_save: rolling back to $( basename ${_SRCFILE} )"
+               grep ${NO_FILE_INDICATOR} ${_SRCFILE} > /dev/null
+               if [ $? -eq 0 ]
+               then
+                       rm -f ${_SRCFILE} ${1}
+               else
+                       mv -f ${_SRCFILE} ${1}
+               fi
+               if [ "${2}" = "true" ]
+               then
+                       _config_changes=1
+               fi
+               rm -f ${1}.save
+       fi
+}
diff --git a/aai-traversal/src/main/scripts/install/siteconf.pl b/aai-traversal/src/main/scripts/install/siteconf.pl
new file mode 100644 (file)
index 0000000..d035851
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+# CC_ID_SITECONF_PL[] = "@(#)/vobs/waas/src/oam/siteconf.pl@@/main/4"
+
+#.Description
+# This perl script takes as input template file, 
+# and one or more configuration files.  It uses the values in the 
+# configuration files as substitutions for the matching tags in the template 
+# file.
+
+#.Constraints
+# The input files must be readable by the script.
+
+#.See Also
+#
+
+use Getopt::Std;
+
+local $dbg=0;
+
+getopts ('dt:c:');
+
+if ($opt_d) {
+       $dbg=$opt_d;
+}
+
+if ($dbg) {
+       print STDERR "opt_d=$opt_d\n";
+       print STDERR "opt_t=$opt_t\n";
+       print STDERR "opt_c=$opt_c\n";
+}
+
+###
+# Print usage if no arguments passed
+if (! $opt_t) {
+       print STDERR "Usage:  $0 -t templatefile -c configfilelist\n";
+       exit (1);
+}
+
+# process the template file variable
+if ($opt_t) {
+       if (! -r $opt_t) {
+               print STDERR "Error:  Can't read template file $opt_t\n";
+               exit (2);
+       }
+       $templatefile = $opt_t;
+}
+else {
+       print STDERR "Error:  You must enter the template file name\n";
+       exit (2);
+}
+
+###
+# Global error flag for return code when exiting
+$err = 0;
+
+$configlist = '';
+if ($opt_c) {
+       $configlist = $opt_c;
+}
+
+# process the site configuration file variable
+if ($configlist) {
+       @siteary = split /,/, $configlist; 
+}
+
+# Add PROJECT_HOME to Conf dictionary
+$Conf{'PROJECT_HOME'} = $ENV{'PROJECT_HOME'};
+
+foreach $arg (@siteary) {
+       if ($dbg) { print STDERR "Opening $arg\n" }
+
+       open(CONF, $arg) || die $!, ", '$arg'\n";
+
+       while (<CONF>) {
+           #1 while chomp();
+           $_ =~ s/[\r\n]$//g; # strip newlines and dos-injected carriage returns
+               if ( /=/ ) {
+                       ($attr,$value) = split(/=/,$_,2);
+                       $value =~ s/\$PHOME/$ENV{'PROJECT_HOME'}/;
+                       $value =~ s/\$PROJECT_HOME/$ENV{'PROJECT_HOME'}/;
+                       $Conf{$attr} = $value;
+               }
+       }
+
+       close CONF;
+}
+
+if ($dbg) { print STDERR "Expanding $templatefile\n" }
+
+# Expand a config file 
+
+open(TEMPLATE, $templatefile) || die $!, ", '$templatefile'\n";
+while (<TEMPLATE>) {
+       # handle strings such as @HTTP_ROOT@@HTTP_PORT@
+       s/@(\w+)@/$Conf{$1}/g;
+       print;
+}
+       
+close TEMPLATE;
+
diff --git a/aai-traversal/src/main/scripts/install/updateQueryData.sh b/aai-traversal/src/main/scripts/install/updateQueryData.sh
new file mode 100644 (file)
index 0000000..798d5b8
--- /dev/null
@@ -0,0 +1,97 @@
+#!/bin/ksh
+
+###
+# ============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=========================================================
+###
+
+PROGNAME=$(basename $0)
+PROJECT_HOME=/opt/app/aai-traversal
+OUTFILE=$PROJECT_HOME/logs/misc/${PROGNAME}.log.$(date +\%Y-\%m-\%d)
+
+TS=$(date "+%Y-%m-%d %H:%M:%S")
+
+CHECK_USER="aaiadmin"
+userid=$( id | cut -f2 -d"(" | cut -f1 -d")" )
+if [ "${userid}" != $CHECK_USER ]; then
+    echo "You must be  $CHECK_USER to run $0. The id used $userid."
+    exit 1
+fi 
+
+error_exit () {
+       echo "${PROGNAME}: failed for ${1:-"Unknown error"} on cmd $2" 1>&2
+       echo "${PROGNAME}: failed for ${1:-"Unknown error"} on cmd $2" >> $OUTFILE
+#      exit ${2:-"1"}
+}
+
+j=0
+for filepath in `ls $PROJECT_HOME/bundleconfig/etc/scriptdata/widget-model-json/*.json|sort -f`
+do
+j=$(expr "$j" + 1)
+filename=$(basename $filepath)
+echo "Begin putTool for widget $filename" | tee -a $OUTFILE
+vers=`grep model-invariant-id $filepath|cut -d':' -f2|cut -d'"' -f2`
+# last parameter will skip put if it exists
+resource=service-design-and-creation/models/model/$vers
+$PROJECT_HOME/scripts/putTool.sh $resource $filepath 412 >> $OUTFILE 2>&1 || error_exit "$resource $filepath" $j
+echo "End putTool for widget $filename" | tee -a $OUTFILE
+done
+
+j=0
+for filepath in `ls $PROJECT_HOME/bundleconfig/etc/scriptdata/named-query-json/*.json|sort -f`
+do
+j=$(expr "$j" + 1)
+filename=$(basename $filepath)
+echo "Begin putTool for named-query $filename" | tee -a $OUTFILE
+vers=`grep named-query-uuid $filepath|cut -d':' -f2|cut -d'"' -f2`
+# last parameter will skip put if it exists
+resource=service-design-and-creation/named-queries/named-query/$vers
+$PROJECT_HOME/scripts/putTool.sh $resource $filepath 412 >> $OUTFILE 2>&1 || error_exit "$resource $filepath" $j
+echo "End putTool for named-query $filename" | tee -a $OUTFILE
+done
+
+j=0
+for filepath in `ls $PROJECT_HOME/bundleconfig/etc/scriptdata/resource-model-json/*.json|sort -f`
+do
+j=$(expr "$j" + 1)
+filename=$(basename $filepath)
+echo "Begin putTool for resource model $filename" | tee -a $OUTFILE
+vers=`grep model-invariant-id $filepath|cut -d':' -f2|cut -d'"' -f2`
+# last parameter will skip put if it exists
+resource=service-design-and-creation/models/model/$vers
+$PROJECT_HOME/scripts/putTool.sh $resource $filepath 412 >> $OUTFILE 2>&1 || error_exit "$resource $filepath" $j
+echo "End putTool for resource model $filename" | tee -a $OUTFILE
+done
+
+j=0
+for filepath in `ls $PROJECT_HOME/bundleconfig/etc/scriptdata/service-model-json/*.json|sort -f`
+do
+j=$(expr "$j" + 1)
+filename=$(basename $filepath)
+echo "Begin putTool for service model $filename" | tee -a $OUTFILE
+vers=`grep model-invariant-id $filepath|cut -d':' -f2|cut -d'"' -f2`
+# last parameter will skip put if it exists
+resource=service-design-and-creation/models/model/$vers
+$PROJECT_HOME/scripts/putTool.sh $resource $filepath 412 >> $OUTFILE 2>&1 || error_exit "$resource $filepath" $j
+echo "End putTool for service model $filename" | tee -a $OUTFILE
+done
+
+echo "$PROGNAME completed ${TS}" | tee -a $OUTFILE
+echo "See output and error file: $OUTFILE"
+
+exit 0
diff --git a/aai-traversal/src/main/scripts/putTool.sh b/aai-traversal/src/main/scripts/putTool.sh
new file mode 100644 (file)
index 0000000..bc89e86
--- /dev/null
@@ -0,0 +1,148 @@
+#!/bin/ksh
+
+###
+# ============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=========================================================
+###
+
+#
+# The script is called with a resource, filepath and an optional argument to
+# ignore HTTP failure codes which would otherwise indicate a failure.
+# It invokes a PUT on the resource with the file using curl
+# Uses aaiconfig.properties for authorization type and url. The HTTP response
+# code is checked. Responses between 200 and 299 are considered success.
+# When the ignore failure code parameter is passed, responses outside of
+# the 200 to 299 range but matching a sub-string of the parameter are
+# considered success. For example, a parameter value of 412 will consider
+# responses in the range of 200 to 299 and 412 successes.
+#
+# method checking parameter list for two strings, and determine if
+# the second string is a sub-string of the first
+contains() {
+    string="$1"
+    substring="$2"
+    if test "${string#*$substring}" != "$string"
+    then
+        return 0    # $substring is in $string
+    else
+        return 1    # $substring is not in $string
+    fi
+}
+
+# remove leading slash when present
+RESOURCE=`echo $1 | sed "s,^/,,"`
+if [ -z $RESOURCE ]; then
+        echo "resource parameter is missing"
+        echo "usage: $0 resource file [expected-failure-codes]"
+        exit 1
+fi
+JSONFILE=$2
+if [ -z $JSONFILE ]; then
+        echo "json file parameter is missing"
+        echo "usage: $0 resource file [expected-failure-codes]"
+        exit 1
+fi
+echo `date` "   Starting $0 for resource $RESOURCE"
+ALLOWHTTPRESPONSES=$3
+
+XFROMAPPID="AAI-TOOLS"
+XTRANSID=`uuidgen`
+
+userid=$( id | cut -f2 -d"(" | cut -f1 -d")" )
+if [ "${userid}" != "aaiadmin" ]; then
+    echo "You must be aaiadmin to run $0. The id used $userid."
+    exit 1
+fi
+
+. /etc/profile.d/aai.sh
+PROJECT_HOME=/opt/app/aai-traversal
+prop_file=$PROJECT_HOME/bundleconfig/etc/appprops/aaiconfig.properties
+log_dir=$PROJECT_HOME/logs/misc
+today=$(date +\%Y-\%m-\%d)
+
+MISSING_PROP=false
+RESTURL=`grep ^aai.server.url= $prop_file |cut -d'=' -f2 |tr -d "\015"`
+if [ -z $RESTURL ]; then
+        echo "Property [aai.server.url] not found in file $prop_file"
+        MISSING_PROP=true
+fi
+USEBASICAUTH=false
+BASICENABLE=`grep ^aai.tools.enableBasicAuth $prop_file |cut -d'=' -f2 |tr -d "\015"`
+if [ -z $BASICENABLE ]; then
+        USEBASICAUTH=false
+else
+        USEBASICAUTH=true
+        CURLUSER=`grep ^aai.tools.username $prop_file |cut -d'=' -f2 |tr -d "\015"`
+        if [ -z $CURLUSER ]; then
+                echo "Property [aai.tools.username] not found in file $prop_file"
+                MISSING_PROP=true
+        fi
+        CURLPASSWORD=`grep ^aai.tools.password $prop_file |cut -d'=' -f2 |tr -d "\015"`
+        if [ -z $CURLPASSWORD ]; then
+                echo "Property [aai.tools.password] not found in file $prop_file"
+                MISSING_PROP=true
+        fi
+fi
+
+if [ $MISSING_PROP = false ]; then
+        if [ $USEBASICAUTH = false ]; then
+                AUTHSTRING="--cert $PROJECT_HOME/bundleconfig/etc/auth/aaiClientPublicCert.pem --key $PROJECT_HOME/bundleconfig/etc/auth/aaiClientPrivateKey.pem"
+        else
+                AUTHSTRING="-u $CURLUSER:$CURLPASSWORD"
+        fi
+        result=`curl --request PUT -sL -w "%{http_code}" -o /dev/null -k $AUTHSTRING -H "X-FromAppId: $XFROMAPPID" -H "X-TransactionId: $XTRANSID" -H "Accept: application/json" -T $JSONFILE $RESTURL$RESOURCE`
+        #echo "result is $result."
+        RC=0;
+        if [ $? -eq 0 ]; then
+                case $result in
+                        +([0-9])?)
+                                #if [[ "$result" -eq 412 || "$result" -ge 200 && $result -lt 300 ]]
+                                if [[ "$result" -ge 200 && $result -lt 300 ]]
+                                then
+                                        echo "PUT result is OK,  $result"
+                                else
+                                        if [ -z $ALLOWHTTPRESPONSES ]; then
+                                                echo "PUT request failed, response code was  $result"
+                                                RC=$result
+                                        else
+                                                contains $ALLOWHTTPRESPONSES $result
+                                                if [ $? -ne 0 ]
+                                                then
+                                                        echo "PUT request failed, unexpected response code was  $result"
+                                                        RC=$result
+                                                else
+                                                        echo "PUT result is expected,  $result"
+                                                fi
+                                        fi
+                                fi
+                                ;;
+                        *)
+                                echo "PUT request failed, response was $result"
+                                RC=-1
+                                ;;
+
+                esac
+        else
+                echo "FAILED to send request to $RESTURL"
+                RC=-1
+        fi
+else
+        echo "usage: $0 resource file [expected-failure-codes]"
+        RC=-1
+fi
+
+echo `date` "   Done $0, returning $RC"
+exit $RC
diff --git a/aai-traversal/src/main/xjb/bindings.xjb b/aai-traversal/src/main/xjb/bindings.xjb
new file mode 100644 (file)
index 0000000..b7629d3
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<jaxb:bindings
+    version="2.1"
+    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <jaxb:bindings scd="x-schema::a" xmlns:a="http://org.openecomp.aai.inventory/v7">
+        <jaxb:schemaBindings>
+            <jaxb:package name="org.openecomp.aai.domain.yang.v7"/>
+        </jaxb:schemaBindings>      
+    </jaxb:bindings>
+    <jaxb:bindings scd="x-schema::a" xmlns:a="http://org.openecomp.aai.inventory/v8">
+        <jaxb:schemaBindings>
+            <jaxb:package name="org.openecomp.aai.domain.yang.v8"/>
+        </jaxb:schemaBindings>      
+    </jaxb:bindings>
+    <jaxb:bindings scd="x-schema::a" xmlns:a="http://org.openecomp.aai.inventory/v9">
+        <jaxb:schemaBindings>
+            <jaxb:package name="org.openecomp.aai.domain.yang"/>
+        </jaxb:schemaBindings>      
+    </jaxb:bindings>
+</jaxb:bindings>
\ No newline at end of file
diff --git a/aai-traversal/src/test/java/org/openecomp/aai/dbgraphgen/DbEdgeGroupTest.java b/aai-traversal/src/test/java/org/openecomp/aai/dbgraphgen/DbEdgeGroupTest.java
new file mode 100644 (file)
index 0000000..e0ad9fc
--- /dev/null
@@ -0,0 +1,104 @@
+/*-
+ * ============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.dbgraphgen;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.junit.Test;
+
+public class DbEdgeGroupTest {
+       
+       @Test
+       public void additionalEdgeWouldBreakMultEdgeRuleMany2Many() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+               
+               Method method = DbEdgeGroup.class.getDeclaredMethod("additionalEdgeWouldBreakMultEdgeRule", String.class, String.class);
+               method.setAccessible(true);
+               
+               assertTrue(!(Boolean)method.invoke(new DbEdgeGroup(), "l-interface", "logical-link"));
+       }
+       
+       @Test
+       public void additionalEdgeWouldBreakMultEdgeRuleMany2ManyRev() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+               
+               Method method = DbEdgeGroup.class.getDeclaredMethod("additionalEdgeWouldBreakMultEdgeRule", String.class, String.class);
+               method.setAccessible(true);
+               
+               assertTrue(!(Boolean)method.invoke(new DbEdgeGroup(), "logical-link", "l-interface"));
+       }
+       
+       @Test
+       public void additionalEdgeWouldBreakMultEdgeRuleOne2One() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+               
+               Method method = DbEdgeGroup.class.getDeclaredMethod("additionalEdgeWouldBreakMultEdgeRule", String.class, String.class);
+               method.setAccessible(true);
+               
+               assertFalse((Boolean)method.invoke(new DbEdgeGroup(), "l-interface", "sriov-vf"));
+       }
+       
+       @Test
+       public void additionalEdgeWouldBreakMultEdgeRuleOne2OneRev() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+               
+               Method method = DbEdgeGroup.class.getDeclaredMethod("additionalEdgeWouldBreakMultEdgeRule", String.class, String.class);
+               method.setAccessible(true);
+               
+               assertFalse((Boolean)method.invoke(new DbEdgeGroup(), "sriov-vf", "l-interface"));
+       }
+       
+       @Test
+       public void additionalEdgeWouldBreakMultEdgeRuleMany2One() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+               
+               Method method = DbEdgeGroup.class.getDeclaredMethod("additionalEdgeWouldBreakMultEdgeRule", String.class, String.class);
+               method.setAccessible(true);
+               
+               assertTrue((Boolean)method.invoke(new DbEdgeGroup(), "cloud-region", "complex"));
+       }
+       
+       @Test
+       public void additionalEdgeWouldBreakMultEdgeRuleMany2OneRev() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+               
+               Method method = DbEdgeGroup.class.getDeclaredMethod("additionalEdgeWouldBreakMultEdgeRule", String.class, String.class);
+               method.setAccessible(true);
+               
+               assertTrue(!(Boolean)method.invoke(new DbEdgeGroup(), "complex", "cloud-region"));
+       }
+       
+       @Test
+       public void additionalEdgeWouldBreakMultEdgeRuleOne2Many() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+               
+               Method method = DbEdgeGroup.class.getDeclaredMethod("additionalEdgeWouldBreakMultEdgeRule", String.class, String.class);
+               method.setAccessible(true);
+               
+               assertTrue(!(Boolean)method.invoke(new DbEdgeGroup(), "cloud-region", "tenant"));
+       }
+       
+       @Test
+       public void additionalEdgeWouldBreakMultEdgeRuleOne2ManyRev() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+               
+               Method method = DbEdgeGroup.class.getDeclaredMethod("additionalEdgeWouldBreakMultEdgeRule", String.class, String.class);
+               method.setAccessible(true);
+               
+               assertFalse((Boolean)method.invoke(new DbEdgeGroup(), "tenant", "cloud-region"));
+       }
+}
diff --git a/aai-traversal/src/test/java/org/openecomp/aai/dbgraphgen/ModelBasedProcessingTest.java b/aai-traversal/src/test/java/org/openecomp/aai/dbgraphgen/ModelBasedProcessingTest.java
new file mode 100644 (file)
index 0000000..30aa812
--- /dev/null
@@ -0,0 +1,86 @@
+/*-
+ * ============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.dbgraphgen;
+//package org.openecomp.aai.dbgen;
+//
+//import java.util.ArrayList;
+//
+//import org.junit.BeforeClass;
+//import org.junit.Rule;
+//import org.junit.Test;
+//import org.junit.rules.ExpectedException;
+//
+//import org.openecomp.aai.exceptions.AAIException;
+//import org.openecomp.aai.ingestModel.DbMaps;
+//import org.openecomp.aai.ingestModel.IngestModelMoxyOxm;
+//import org.openecomp.aai.util.AAIConstants;
+//
+//public class ModelBasedProcessingTest {
+//     
+//     private static DbMaps dbMaps = null;
+//     private static ModelBasedProcessing processor;
+//     @BeforeClass
+//     public static void configure() throws Exception {
+//             System.setProperty("AJSC_HOME", ".");
+//             System.setProperty("BUNDLECONFIG_DIR", "bundleconfig-local");
+//             ArrayList<String> apiVersions = new ArrayList<String>();
+//             apiVersions.add("v9");
+//             apiVersions.add("v8");
+//             apiVersions.add("v7");
+//             apiVersions.add("v2");
+//             IngestModelMoxyOxm m = new IngestModelMoxyOxm();
+//             m.init(apiVersions);
+//             
+//             dbMaps = m.dbMapsContainer.get(AAIConstants.AAI_DEFAULT_API_VERSION);
+//             processor = new ModelBasedProcessing();
+//             
+//     }
+//     
+//     @Rule
+//     public ExpectedException expectedEx = ExpectedException.none();
+//
+//     @Test
+//     public void check4EdgeRuleThrowsExceptionWhenNodeTypeADoesNotExist() throws Exception {
+//             String nodeTypeA = "cccomplex";
+//             String nodeTypeB = "pserver";
+//         expectedEx.expect(AAIException.class);
+//         expectedEx.expectMessage("AAI_6115");
+//         processor.check4EdgeRule(nodeTypeA, nodeTypeB, dbMaps);    
+//     }
+//     
+//     @Test
+//     public void check4EdgeRuleThrowsExceptionWhenNodeTypeBDoesNotExist() throws Exception {
+//             String nodeTypeA = "complex";
+//             String nodeTypeB = "ppppserver";
+//         expectedEx.expect(AAIException.class);
+//         expectedEx.expectMessage("AAI_6115");
+//         processor.check4EdgeRule(nodeTypeA, nodeTypeB, dbMaps);    
+//     }
+//     
+//     @Test
+//     public void check4EdgeRuleThrowsExceptionWhenNoRuleExists() throws Exception {
+//             String nodeTypeA = "complex";
+//             String nodeTypeB = "service";
+//             expectedEx.expect(AAIException.class);
+//         expectedEx.expectMessage("AAI_6120");
+//         processor.check4EdgeRule(nodeTypeA, nodeTypeB, dbMaps);    
+//     }
+//}
diff --git a/aai-traversal/src/test/java/org/openecomp/aai/dbgraphmap/SearchGraphEdgeRuleTest.java b/aai-traversal/src/test/java/org/openecomp/aai/dbgraphmap/SearchGraphEdgeRuleTest.java
new file mode 100644 (file)
index 0000000..7484353
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============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.dbgraphmap;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import org.openecomp.aai.exceptions.AAIException;
+
+public class SearchGraphEdgeRuleTest {
+       @Rule
+       public ExpectedException expectedEx = ExpectedException.none();
+       
+       @Test
+       public void getEdgeLabelTest() throws AAIException {
+               String[] label = SearchGraph.getEdgeLabel("customer", "service-subscription");
+               
+               assertEquals("subscribesTo", label[0]);
+       }
+       
+       @Test
+       public void getEdgeLabelThrowsExceptionWhenNoRuleExists() throws Exception {
+               String nodeTypeA = "complex";
+               String nodeTypeB = "service";
+               expectedEx.expect(AAIException.class);
+               expectedEx.expectMessage("No EdgeRule found for passed nodeTypes: complex, service.");
+           SearchGraph.getEdgeLabel(nodeTypeA, nodeTypeB);
+       }
+       
+       @Test
+       public void getEdgeLabelThrowsExceptionWhenNodeTypesDoNotExist() throws Exception {
+               String nodeTypeA = "A";
+               String nodeTypeB = "B";
+               expectedEx.expect(AAIException.class);
+           expectedEx.expectMessage("No EdgeRule found for passed nodeTypes: A, B.");
+           SearchGraph.getEdgeLabel(nodeTypeA, nodeTypeB);    
+       }
+}
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
new file mode 100644 (file)
index 0000000..0df8ee3
--- /dev/null
@@ -0,0 +1,85 @@
+/*-
+ * ============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 static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.serialization.db.EdgeRules;
+import org.openecomp.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
+
+public abstract class QueryTest {
+       
+       protected Graph graph;
+       private GremlinServerSingleton gremlinServerSingleton;
+       private GremlinGroovyShellSingleton shell;
+       
+       protected final List<Vertex> expectedResult = new ArrayList<>();
+       protected final EdgeRules rules = EdgeRules.getInstance();
+       
+       
+       public QueryTest() throws AAIException, NoEdgeRuleFoundException {
+               setUp();
+       }
+       public void setUp() throws AAIException, NoEdgeRuleFoundException {
+               System.setProperty("AJSC_HOME", ".");
+               System.setProperty("BUNDLECONFIG_DIR", "bundleconfig-local");
+               graph = TinkerGraph.open();
+               createGraph();
+               gremlinServerSingleton = GremlinServerSingleton.getInstance();
+               shell = GremlinGroovyShellSingleton.getInstance();
+       }
+       
+       public void run() {
+               
+               String query = "g." + gremlinServerSingleton.getStoredQuery(getQueryName());
+               
+               Map<String, Object> params = new HashMap<>();
+               
+               GraphTraversal<Vertex, Vertex> g = graph.traversal().V();
+               addStartNode(g);
+               params.put("g", g);
+               addParam(params);
+               GraphTraversal<Vertex, Vertex> result = (GraphTraversal<Vertex, Vertex>)shell.executeTraversal(query, params);
+               
+               List<Vertex> vertices = result.toList();
+               assertTrue("all vertices found", vertices.containsAll(expectedResult) && expectedResult.containsAll(vertices));
+
+       }
+       
+       protected abstract void createGraph() throws AAIException, NoEdgeRuleFoundException;
+               
+       protected abstract String getQueryName();
+       
+       protected abstract void addStartNode(GraphTraversal<Vertex, Vertex> g);
+       
+       protected abstract void addParam(Map<String, Object> params);
+}
diff --git a/aai-traversal/src/test/java/org/openecomp/aai/rest/util/ValidateEncodingTest.java b/aai-traversal/src/test/java/org/openecomp/aai/rest/util/ValidateEncodingTest.java
new file mode 100644 (file)
index 0000000..8c6450d
--- /dev/null
@@ -0,0 +1,101 @@
+/*-
+ * ============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.util;
+
+import static org.junit.Assert.*;
+
+import java.io.UnsupportedEncodingException;
+
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriInfo;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class ValidateEncodingTest {
+
+       
+       @Test
+       public void badPath() throws UnsupportedEncodingException {
+               String badPath = "/aai/v6/network/vces/vce/blahh::blach/others/other/jklfea{}";
+               UriInfo mockUriInfo = getMockUriInfo(badPath, new MultivaluedHashMap<String, String>());
+               ValidateEncoding validator = ValidateEncoding.getInstance();
+               
+               assertEquals(false, validator.validate(mockUriInfo));
+       }
+       
+       @Test
+       public void goodPath() throws UnsupportedEncodingException {
+               String goodPath = "/aai/v6/network/vces/vce/blahh%3A%3Ablach/others/other/jklfea%7B%7D";
+               UriInfo mockUriInfo = getMockUriInfo(goodPath, new MultivaluedHashMap<String, String>());
+               ValidateEncoding validator = ValidateEncoding.getInstance();
+               
+               assertEquals(true, validator.validate(mockUriInfo));    
+       }
+       
+       @Test
+       public void badQueryParamsKey() throws UnsupportedEncodingException {
+               MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
+               map.putSingle("blahblah", "test");
+               map.putSingle("blahblah", "test2");
+               map.putSingle("bad::bad", "test3");
+               UriInfo mockUriInfo = getMockUriInfo("", map);
+
+               ValidateEncoding validator = ValidateEncoding.getInstance();
+               
+               assertEquals(false, validator.validate(mockUriInfo));
+               
+       }
+       @Test
+       public void badQueryParamsValue() throws UnsupportedEncodingException {
+               MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
+               map.putSingle("blahblah", "test");
+               map.putSingle("blahblah", "test//:2");
+               map.putSingle("badbad", "test3");
+               UriInfo mockUriInfo = getMockUriInfo("", map);
+
+               ValidateEncoding validator = ValidateEncoding.getInstance();
+               
+               assertEquals(false, validator.validate(mockUriInfo));
+       }
+       @Test
+       public void goodQueryParams() throws UnsupportedEncodingException {
+               MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
+               map.putSingle("blahblah", "test");
+               map.putSingle("blahblah", "test2");
+               map.putSingle("badbad", "~test%2F%2F%3A3");
+               UriInfo mockUriInfo = getMockUriInfo("", map);
+
+               ValidateEncoding validator = ValidateEncoding.getInstance();
+               
+               assertEquals(true, validator.validate(mockUriInfo));
+       }
+       
+       private UriInfo getMockUriInfo(String path, MultivaluedMap<String, String> map) {
+               UriInfo mockUriInfo = Mockito.mock(UriInfo.class);
+               Mockito.when(mockUriInfo.getPath(false)).thenReturn(path);
+               Mockito.when(mockUriInfo.getQueryParameters(false)).thenReturn(map);
+               
+               return mockUriInfo;
+       }
+       
+}
diff --git a/aai-traversal/src/test/java/org/openecomp/aai/transforms/JoltTestUtil.java b/aai-traversal/src/test/java/org/openecomp/aai/transforms/JoltTestUtil.java
new file mode 100644 (file)
index 0000000..7df2790
--- /dev/null
@@ -0,0 +1,61 @@
+/*-
+ * ============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.transforms;
+
+
+import java.io.IOException;
+
+import org.junit.Assert;
+
+import com.bazaarvoice.jolt.ArrayOrderObliviousDiffy;
+import com.bazaarvoice.jolt.Diffy;
+import com.bazaarvoice.jolt.JsonUtils;
+
+public class JoltTestUtil {
+
+    private static final Diffy diffy = new Diffy();
+    private static final Diffy arrayOrderObliviousDiffy = new ArrayOrderObliviousDiffy();
+
+    public static void runDiffy( String failureMessage, Object expected, Object actual ) throws IOException {
+        runDiffy( diffy, failureMessage, expected, actual );
+    }
+
+    public static void runDiffy( Object expected, Object actual ) throws IOException {
+        runDiffy( diffy, "Failed", expected, actual );
+    }
+
+    public static void runArrayOrderObliviousDiffy( String failureMessage, Object expected, Object actual ) throws IOException {
+        runDiffy( arrayOrderObliviousDiffy, failureMessage, expected, actual );
+    }
+
+    public static void runArrayOrderObliviousDiffy( Object expected, Object actual ) throws IOException {
+        runDiffy( arrayOrderObliviousDiffy, "Failed", expected, actual );
+    }
+
+
+    private static void runDiffy( Diffy diffy, String failureMessage, Object expected, Object actual ) {
+        String actualObject = JsonUtils.toPrettyJsonString( actual );
+        Diffy.Result result = diffy.diff( expected, actual );
+        if (!result.isEmpty()) {
+            Assert.fail( "\nActual object\n" + actualObject + "\n" + failureMessage + "\nDiffy output\n" + result.toString());
+        }
+    }
+}
diff --git a/aai-traversal/src/test/java/org/openecomp/aai/transforms/LowerHyphenToLowerCamelConverterTest.java b/aai-traversal/src/test/java/org/openecomp/aai/transforms/LowerHyphenToLowerCamelConverterTest.java
new file mode 100644 (file)
index 0000000..3dc5299
--- /dev/null
@@ -0,0 +1,73 @@
+/*-
+ * ============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.transforms;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.junit.Assert.*;
+
+@RunWith(Parameterized.class)
+public class LowerHyphenToLowerCamelConverterTest {
+
+    private Converter converter = new LowerHyphenToLowerCamelConverter();
+
+    private String input;
+    private String expected;
+
+    public LowerHyphenToLowerCamelConverterTest(String input, String expected){
+        this.input  = input;
+        this.expected = expected;
+    }
+
+    /**
+     * Data Provider for the Lower Hyphen to Camel Converter Tests
+     * Make sure the capitalization is not lost during the conversion
+     * @return
+     */
+    @Parameters
+    public static Collection<Object[]> data(){
+
+        return Arrays.asList(new Object[][]{
+            {null, null},
+            {"test-name", "testName"},
+            {"test---name", "testName"},            // Case multiple
+            {"testName", "testName"},               // Case where upper case word shouldn't be lowercased
+            {"test-name-cool", "testNameCool"},
+            {"test-name-Cool", "testNameCool"},
+            {"test-name-Cool-Name-wow----Rest", "testNameCoolNameWowRest"},
+            {"test-name#fast#", "testName#fast#"},
+            {"test-name---", "testName"},
+            {"----test-name", "TestName"},
+        });
+    }
+
+    @Test
+    public void testIfInputSuccessfullyModified(){
+        String actual = converter.convert(input);
+        assertEquals(expected, actual);
+    }
+}
diff --git a/aai-traversal/src/test/java/org/openecomp/aai/transforms/MapTraverserTest.java b/aai-traversal/src/test/java/org/openecomp/aai/transforms/MapTraverserTest.java
new file mode 100644 (file)
index 0000000..e3b7760
--- /dev/null
@@ -0,0 +1,56 @@
+/*-
+ * ============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.transforms;
+
+import org.openecomp.aai.transforms.LowerCamelToLowerHyphenConverter;
+import org.openecomp.aai.transforms.MapTraverser;
+import com.bazaarvoice.jolt.JsonUtils;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Map;
+
+public class MapTraverserTest {
+
+    private final String testResources = "src/test/resources/maputils/testcases/";
+
+    private String[] testCases = { "TestCase1.json", "TestCase2.json" };
+    private MapTraverser traverser = new MapTraverser(new LowerCamelToLowerHyphenConverter());
+
+    @Test(expected = NullPointerException.class)
+    public void testIfMapIsNullThrowNullPointerException(){
+        Map<String, Object> map = null;
+        traverser.convertKeys(map);
+    }
+
+    @Test
+    public void runTestCases() throws IOException {
+
+        for(String testCase : testCases){
+            Map<String, Object> values = JsonUtils.filepathToMap(testResources + testCase);
+
+            Object input = values.get("input");
+            Object actual = traverser.convertKeys((Map<String, Object>)input);
+            Object output = values.get("output");
+            JoltTestUtil.runArrayOrderObliviousDiffy( "failed case " + testCase, output, actual );
+        }
+    }
+}
diff --git a/aai-traversal/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties b/aai-traversal/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties
new file mode 100644 (file)
index 0000000..a29948c
--- /dev/null
@@ -0,0 +1,105 @@
+###
+# ============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=========================================================
+###
+
+####################################################################
+#  REMEMBER TO THINK ABOUT ENVIRONMENTAL DIFFERENCES AND CHANGE THE
+#  TEMPLATE AND *ALL* DATAFILES
+####################################################################
+
+aai.config.checktime=1000
+
+# this could come from siteconfig.pl?
+aai.config.nodename=AutomaticallyOverwritten
+
+aai.logging.hbase.interceptor=true
+aai.logging.hbase.enabled=true
+aai.logging.hbase.logrequest=true
+aai.logging.hbase.logresponse=true
+
+aai.logging.trace.enabled=true
+aai.logging.trace.logrequest=false
+aai.logging.trace.logresponse=false
+
+aai.transaction.logging=true
+aai.transaction.logging.get=true
+aai.transaction.logging.post=true
+
+aai.server.url.base=https://localhost:8446/aai/
+aai.server.url=https://localhost:8446/aai/v10/
+aai.global.callback.url=https://localhost:8446/aai/
+
+aai.auth.cspcookies_on=false
+aai.dbmodel.filename=ex5.json
+aai.truststore.filename=aai_keystore
+aai.truststore.passwd.x=
+aai.keystore.filename=aai-client-cert.p12
+aai.keystore.passwd.x=
+
+# for transaction log
+hbase.table.name=aailogging-dev1.dev
+hbase.notificationTable.name=aainotification-dev1.dev
+hbase.table.timestamp.format=YYYYMMdd-HH:mm:ss:SSS
+hbase.zookeeper.quorum=ONAPserverTBD
+hbase.zookeeper.property.clientPort=2181
+hbase.zookeeper.znode.parent=/hbase-unsecure
+
+# single primary server
+aai.primary.filetransfer.serverlist=ONAPserverTBD
+aai.primary.filetransfer.primarycheck=echo:8443/aai/util/echo
+aai.primary.filetransfer.pingtimeout=5000
+aai.primary.filetransfer.pingcount=5
+
+#rsync properties
+aai.rsync.command=rsync
+aai.rsync.options.list=-v|-t
+aai.rsync.remote.user=aaiadmin
+aai.rsync.enabled=y
+
+aai.notification.current.version=v10
+aai.notificationEvent.default.status=UNPROCESSED
+aai.notificationEvent.default.eventType=AAI-EVENT
+aai.notificationEvent.default.domain=devINT1
+aai.notificationEvent.default.sourceName=aai
+aai.notificationEvent.default.sequenceNumber=0
+aai.notificationEvent.default.severity=NORMAL
+aai.notificationEvent.default.version=v9
+# This one lets us enable/disable resource-version checking on updates/deletes
+aai.resourceversion.enableflag=true
+aai.logging.maxStackTraceEntries=10
+aai.default.api.version=v9
+
+# Used by Model-processing code
+aai.model.delete.sleep.per.vtx.msec=500
+aai.model.query.resultset.maxcount=30
+aai.model.query.timeout.sec=90
+aai.model.proc.max.levels=50
+aai.edgeTag.proc.max.levels=50
+
+# Used by the ForceDelete tool
+aai.forceDel.protected.nt.list=cloud-region
+aai.forceDel.protected.edge.count=10
+aai.forceDel.protected.descendant.count=10
+
+aai.dmaap.workload.enableEventProcessing=true
+
+aai.realtime.clients=RO,SDNC,MSO
+
+aai.server.rebind=g
diff --git a/aai-traversal/src/test/resources/bundleconfig-local/etc/appprops/error.properties b/aai-traversal/src/test/resources/bundleconfig-local/etc/appprops/error.properties
new file mode 100644 (file)
index 0000000..4e98d62
--- /dev/null
@@ -0,0 +1,163 @@
+# Adding comment trying to trigger a build
+#-------------------------------------------------------------------------------                                                                                            ----------
+#Key=Disposition:Category:Severity:Error Code:HTTP ResponseCode:RESTError Code:Error Message
+#-------------------------------------------------------------------------------                                                                                            ----------
+# testing code, please don't change unless error utility source code changes
+AAI_TESTING=5:2:WARN:0000:400:0001:Error code for testing
+
+# General success
+AAI_0000=0:0:INFO:0000:200:0000:Success
+
+# health check success
+AAI_0001=0:0:INFO:0001:200:0001:Success X-FromAppId=%1 X-TransactionId=%2 
+AAI_0002=0:0:INFO:0002:200:0001:Successful health check
+
+# Success with additional info
+AAI_0003=0:3:INFO:0003:202:0003:Success with additional info performing %1 on %2. Added %3 with key %4
+AAI_0004=0:3:INFO:0004:202:0003:Added prerequisite object to db
+
+#--- aairest: 3000-3299
+# svc errors
+AAI_3000=5:2:INFO:3000:400:3000:Invalid input performing %1 on %2
+AAI_3001=5:6:INFO:3001:404:3001:Resource not found for %1 using id %2
+AAI_3002=5:1:WARN:3002:400:3002:Error writing output performing %1 on %2
+AAI_3003=5:1:WARN:3003:400:3003:Failed to make edge to missing target node of type %3 with keys %4 performing %1 on %2
+AAI_3005=5:6:WARN:3005:404:3001:Node cannot be directly accessed for read, must be accessed via ancestor(s)
+AAI_3006=5:6:WARN:3006:404:3001:Node cannot be directly accessed for write, must be accessed via ancestor(s)
+AAI_3007=5:6:INFO:3007:410:3007:This version (%1) of the API is retired, please migrate to %2
+AAI_3008=5:6:ERROR:3008:400:3008:URI is not encoded in UTF-8
+AAI_3009=5:6:ERROR:3009:400:3002:Malformed URL
+# pol errors
+AAI_3100=5:1:WARN:3100:400:3100:Unsupported operation %1
+AAI_3101=5:1:WARN:3101:403:3101:Attempt by client %1 to execute API %2
+AAI_3102=5:1:WARN:3102:400:3102:Error parsing input performing %1 on %2
+AAI_3300=5:1:WARN:3300:403:3300:Unauthorized
+AAI_3301=5:1:WARN:3301:401:3301:Stale credentials
+AAI_3302=5:1:WARN:3302:401:3301:Not authenticated
+AAI_3303=5:1:ERROR:3303:403:3300:Too many objects would be returned by this request, please refine your request and retry
+
+#--- aaigen: 4000-4099
+AAI_4000=5:4:ERROR:4000:500:3002:Internal Error
+AAI_4001=5:4:FATAL:4001:500:3002:Configuration file not found
+AAI_4002=5:4:FATAL:4002:500:3002:Error reading Configuration file
+AAI_4003=5:4:ERROR:4003:500:3002:Error writing to log file
+AAI_4004=5:4:FATAL:4004:500:3002:Error reading/parsing the error properties file
+AAI_4005=5:4:FATAL:4005:500:3002:Missing or invalid configuration parameter
+AAI_4006=5:4:FATAL:4006:500:3002:Unexpected error in service
+AAI_4007=5:4:ERROR:4007:500:3102:Input parsing error
+AAI_4008=5:4:ERROR:4008:500:3002:Output parsing error
+AAI_4009=4:0:ERROR:4009:400:3000:Invalid X-FromAppId in header
+AAI_4010=4:0:ERROR:4010:400:3000:Invalid X-TransactionId in header
+AAI_4011=5:4:ERROR:4011:500:3002:Missing data for REST error response
+AAI_4012=5:4:ERROR:4012:500:3002:Bad rule data in RestRules 
+AAI_4013=5:4:ERROR:4013:500:3002:Error connecting to AAI REST API
+AAI_4014=4:0:ERROR:4014:400:3000:Invalid Accept header
+AAI_4015=4:0:ERROR:4015:400:3000:You must provide at least one indexed property
+AAI_4016=4:0:ERROR:4016:400:3000:The depth parameter must be a number or the string "all"
+AAI_4017=5:2:INFO:4017:400:3000:Could not set property
+AAI_4018=5:2:ERROR:4018:400:3000:Unable to convert the string to integer
+#--- aaidbmap: 5101-5199
+AAI_5101=5:4:FATAL:5101:500:3002:Could not connect to database
+AAI_5102=5:4:FATAL:5102:500:3002:Graph database is null after open
+AAI_5103=5:4:ERROR:5103:500:3002:Unexpected error during commit
+AAI_5104=5:4:ERROR:5104:500:3002:Unexpected error during rollback
+AAI_5105=5:4:ERROR:5105:500:3002:Unexpected error reading/updating database
+AAI_5106=5:4:WARN:5106:404:3001:Node not found
+AAI_5107=5:2:WARN:5107:400:3000:Required information missing
+AAI_5108=5:2:WARN:5108:200:0:Unexpected information in request being ignored
+
+#--- aaidbgen: 6101-6199
+AAI_6101=5:4:ERROR:6101:500:3002:null TitanGraph object passed
+AAI_6102=5:4:WARN:6102:400:3000:Passed-in property is not valid for this nodeType
+AAI_6103=5:4:WARN:6103:400:3000:Required Node-property not found in input data
+AAI_6104=5:4:WARN:6104:400:3000:Required Node-property was passed with no data
+AAI_6105=5:4:WARN:6105:400:3000:Node-Key-Property not defined in DbMaps
+AAI_6106=5:4:WARN:6106:400:3000:Passed-in property is not valid for this edgeType
+AAI_6107=5:4:WARN:6107:400:3000:Required Edge-property not found in input data
+AAI_6108=5:4:WARN:6108:400:3000:Required Edge-property was passed with no data
+AAI_6109=5:4:WARN:6109:400:3000:Bad dependent Node value
+AAI_6110=5:4:ERROR:6110:400:3100:Node cannot be deleted
+AAI_6111=5:4:ERROR:6111:400:3000:JSON processing error
+AAI_6112=5:4:ERROR:6112:400:3000:More than one node found by getUniqueNode()
+AAI_6114=5:4:INFO:6114:404:3001:Node Not Found
+AAI_6115=5:4:ERROR:6115:400:3000:Unrecognized NodeType
+AAI_6116=5:4:ERROR:6116:400:3000:Unrecognized Property
+AAI_6117=5:4:ERROR:6117:400:3000:Uniqueness constraint violated
+AAI_6118=5:4:ERROR:6118:400:3000:Required Field not passed.
+AAI_6120=5:4:ERROR:6120:400:3000:Bad Parameter Passed
+AAI_6121=5:4:ERROR:6121:400:3000:Problem with internal AAI reference data
+AAI_6122=5:4:ERROR:6122:400:3000:Data Set not complete in DB for this request
+AAI_6123=5:4:ERROR:6123:500:3000:Bad Data found by DataGrooming Tool - Investigate
+AAI_6124=5:4:ERROR:6124:500:3000:File read/write error
+AAI_6125=5:4:WARN:6125:500:3000:Problem Pulling Data Set
+AAI_6126=5:4:ERROR:6126:400:3000:Edge cannot be deleted
+AAI_6127=5:4:INFO:6127:404:3001:Edge Not Found
+AAI_6128=5:4:INFO:6128:500:3000:Unexpected error
+AAI_6129=5:4:INFO:6129:404:3003:Error making edge to target node
+AAI_6130=5:4:WARN:6130:412:3000:Precondition Required
+AAI_6131=5:4:WARN:6131:412:3000:Precondition Failed
+AAI_6132=5:4:WARN:6132:400:3000:Bad Model Definition 
+AAI_6133=5:4:WARN:6133:400:3000:Bad Named Query Definition
+AAI_6134=5:4:ERROR:6134:500:6134:Could not persist transaction to storage back end. Exhausted retry amount
+AAI_6135=5:4:WARN:6135:412:3000:Resource version specified on create
+AAI_6136=5:4:ERROR:6136:400:3000:Object cannot hold multiple items
+AAI_6137=5:4:ERROR:6137:400:3000:Cannot perform writes on multiple vertices
+AAI_6138=5:4:ERROR:6138:400:3000:Cannot delete multiple vertices
+AAI_6139=5:4:ERROR:6139:404:3000:Attempted to add edge to vertex that does not exist
+AAI_6140=5:4:ERROR:6140:400:3000:Edge multiplicity violated
+AAI_6141=5:4:WARN:6141:400:3000:Please Refine Query
+AAI_6142=5:4:INFO:6142:400:3000:Retrying transaction
+AAI_6143=5:4:INFO:6143:400:3000:Ghost vertex found
+AAI_6144=5:4:WARN:6144:400:3000:Cycle found in graph
+AAI_6145=5:4:ERROR:6145:400:3000:Cannot create a nested/containment edge via relationship
+
+#--- aaicsvp: 7101-7199
+AAI_7101=5:4:ERROR:7101:500:3002:Unexpected error in CSV file processing
+AAI_7102=5:4:ERROR:7102:500:3002:Error in cleanup temporary directory
+#AAI_7103=4:2:ERROR:7103:500:3002:Unsupported user
+AAI_7104=5:4:ERROR:7104:500:3002:Failed to create directory
+AAI_7105=5:4:ERROR:7105:500:3002:Temporary directory exists
+AAI_7106=5:4:ERROR:7106:500:3002:Cannot delete
+AAI_7107=5:4:ERROR:7107:500:3002:Input file does not exist
+AAI_7108=5:4:ERROR:7108:500:3002:Output file does not exist
+AAI_7109=5:4:ERROR:7109:500:3002:Error closing file
+AAI_7110=5:4:ERROR:7110:500:3002:Error loading/reading properties file
+AAI_7111=5:4:ERROR:7111:500:3002:Error executing shell script
+AAI_7112=5:4:ERROR:7112:500:3002:Error creating output file
+AAI_7113=5:4:ERROR:7113:500:3002:Trailer record error
+AAI_7114=5:4:ERROR:7114:500:3002:Input file error
+AAI_7115=5:4:ERROR:7115:500:3002:Unexpected error
+AAI_7116=5:4:ERROR:7116:500:3002:Request error 
+AAI_7117=5:4:ERROR:7117:500:3002:Error in get http client object
+AAI_7118=5:4:ERROR:7118:500:3002:Script Error
+AAI_7119=5:4:ERROR:7119:500:3002:Unknown host
+
+#--- aaisdnc: 7201-7299
+AAI_7202=5:4:ERROR:7202:500:3002:Error getting connection to odl
+AAI_7203=5:4:ERROR:7203:500:3002:Unexpected error calling DataChangeNotification API
+AAI_7204=5:4:ERROR:7204:500:3002:Error returned by DataChangeNotification API
+AAI_7205=5:4:ERROR:7205:500:3002:Unexpected error running notifySDNCOnUpdate
+AAI_7206=5:4:ERROR:7206:500:3002:Invalid data returned from ODL
+
+#--- NotificationEvent, using UEB space
+AAI_7350=5:4:ERROR:7305:500:3002:Notification event creation failed
+
+#--- aairestctlr: 7401-7499
+AAI_7401=5:4:ERROR:7401:500:3002:Error connecting to AAI REST API
+AAI_7402=5:4:ERROR:7402:500:3002:Unexpected error
+AAI_7403=5:4:WARN:7403:400:3001:Request error
+AAI_7404=5:4:INFO:7404:404:3001:Node not found
+
+#--- aaiauth: 9101-9199
+AAI_9101=5:0:WARN:9101:403:3300:User is not authorized to perform function
+AAI_9102=5:0:WARN:9102:401:3301:Refresh credentials from source
+AAI_9103=5:0:WARN:9103:403:3300:User not found
+AAI_9104=5:0:WARN:9104:401:3302:Authentication error
+AAI_9105=5:0:WARN:9105:403:3300:Authorization error
+AAI_9106=5:0:WARN:9106:403:3300:Invalid AppId
+#AAI_9107=5:0:WARN:9107:403:3300:No Username in Request
+AAI_9107=5:0:WARN:9107:403:3300:SSL is not provided in request, please contact admin
+
+#--- aaiinstar: 9201-9299
+AAI_9201=5:4:ERROR:9201:500:3002:Unable to send notification
+AAI_9202=5:4:ERROR:9202:500:3002:Unable to start a thread
diff --git a/aai-traversal/src/test/resources/bundleconfig-local/etc/auth/aai_policy.json b/aai-traversal/src/test/resources/bundleconfig-local/etc/auth/aai_policy.json
new file mode 100644 (file)
index 0000000..9706ce9
--- /dev/null
@@ -0,0 +1,37 @@
+{
+    "roles": [{
+            "name": "testRole",
+            "functions": [{
+                    "name": "testFunction",
+                    "methods": [{
+                            "name": "GET"
+                        }, {
+                            "name": "DELETE"
+                        }, {
+                            "name": "PUT"
+                        }
+                    ]
+                }
+            ],
+            "users": [{
+                    "username": "testUser"
+                }
+            ]
+        }, {
+            "name": "testBasicAuth",
+            "functions": [{
+                    "name": "testBasicAuthFuncyion",
+                    "methods": [{
+                            "name": "GET"
+                        }
+                    ]
+                }
+            ],
+            "users": [{
+                    "user": "testBasicAuthUser",
+                    "pass": "OBF:1ytc1vu91v2p1rxf1mqh1v8s1z0d1msn1san1mqf1z0h1v9u1msl1rvf1v1p1vv11yta"
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/aai-traversal/src/test/resources/config/etc/titan-cached.properties b/aai-traversal/src/test/resources/config/etc/titan-cached.properties
new file mode 100644 (file)
index 0000000..6408909
--- /dev/null
@@ -0,0 +1,37 @@
+###
+# ============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=========================================================
+###
+
+query.fast-property=true
+# the following parameters are not reloaded automatically and require a manual bounce
+storage.backend=inmemory
+storage.hostname=ONAPserverTBD
+
+#schema.default=none
+storage.lock.wait-time=300
+storage.hbase.table=aaigraph-dev1.dev
+storage.hbase.ext.zookeeper.znode.parent=/hbase-unsecure
+#caching on
+cache.db-cache = true
+cache.db-cache-clean-wait = 20
+cache.db-cache-time = 180000
+cache.db-cache-size = 0.3
+
+#load graphson file on startup
+load.snapshot.file=false
diff --git a/aai-traversal/src/test/resources/config/etc/titan-realtime.properties b/aai-traversal/src/test/resources/config/etc/titan-realtime.properties
new file mode 100644 (file)
index 0000000..c50b141
--- /dev/null
@@ -0,0 +1,34 @@
+###
+# ============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=========================================================
+###
+
+query.fast-property=true
+# the following parameters are not reloaded automatically and require a manual bounce
+storage.backend=inmemory
+storage.hostname=ONAPserverTBD
+
+#schema.default=none
+storage.lock.wait-time=300
+storage.hbase.table=aaigraph-dev1.dev
+storage.hbase.ext.zookeeper.znode.parent=/hbase-unsecure
+# Setting db-cache to false ensure the fastest propagation of changes across servers
+cache.db-cache = false
+
+#load graphson file on startup
+load.snapshot.file=true
diff --git a/aai-traversal/src/test/resources/inmemory_titan.properties b/aai-traversal/src/test/resources/inmemory_titan.properties
new file mode 100644 (file)
index 0000000..46695d6
--- /dev/null
@@ -0,0 +1,21 @@
+###
+# ============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=========================================================
+###
+
+storage.backend=inmemory
diff --git a/aai-traversal/src/test/resources/log4j.properties b/aai-traversal/src/test/resources/log4j.properties
new file mode 100644 (file)
index 0000000..2e68f61
--- /dev/null
@@ -0,0 +1,3 @@
+log4j.logger.org.apache.zookeeper=WARN
+log4j.logger.org.apache.hadoop.hbase.zookeeper=WARN
+log4j.logger.org.apache.hadoop.hbase.client=WARN
\ No newline at end of file
diff --git a/aai-traversal/src/test/resources/logback.xml b/aai-traversal/src/test/resources/logback.xml
new file mode 100644 (file)
index 0000000..735e70d
--- /dev/null
@@ -0,0 +1,292 @@
+<!--
+  ============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=========================================================
+  -->
+
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+       <contextName>${module.ajsc.namespace.name}</contextName>
+       <jmxConfigurator />
+       <property name="logDirectory" value="${AJSC_HOME}/logs" />
+       
+       <!-- Example evaluator filter applied against console appender -->
+       <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+               <filter class="ch.qos.logback.classic.filter.LevelFilter">
+                       <!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> -->
+                       <level>ERROR</level>
+                       <onMatch>ACCEPT</onMatch>
+                       <onMismatch>DENY</onMismatch>
+               </filter>
+               <encoder>
+                       <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - %msg%n
+                       </pattern>
+               </encoder>
+       </appender>
+
+       <appender name="METRIC"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.LevelFilter">
+                       <level>INFO</level>
+                       <onMatch>ACCEPT</onMatch>
+                       <onMismatch>DENY</onMismatch>
+               </filter>
+               <file>${logDirectory}/rest/metric.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/metric.log.%d{yyyy-MM-dd}</fileNamePattern>
+               </rollingPolicy>
+               <!--  <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize>
+               </triggeringPolicy> -->
+               <encoder>
+                       <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%m%n</pattern>
+               </encoder>
+       </appender>
+
+       <appender name="DEBUG"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>DEBUG</level>
+                       <onMatch>ACCEPT</onMatch>
+                       <onMismatch>DENY</onMismatch>
+               </filter>
+               <file>${logDirectory}/rest/debug.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/debug.log.%d{yyyy-MM-dd}</fileNamePattern>
+               </rollingPolicy>
+               <!--  <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize> 
+               </triggeringPolicy>-->
+               <encoder>
+                       <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%m%n</pattern>
+               </encoder>
+       </appender>
+
+       <appender name="ERROR"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+                       <level>WARN</level>
+                       <onMatch>ACCEPT</onMatch>
+                       <onMismatch>DENY</onMismatch>
+               </filter>
+               <file>${logDirectory}/rest/error.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/error.log.%d{yyyy-MM-dd}</fileNamePattern>
+               </rollingPolicy>
+               <!-- <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize>
+               </triggeringPolicy>-->
+               <encoder>
+                       <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - %msg%n"</pattern> -->
+                       <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%m%n</pattern>
+               </encoder>
+       </appender>
+       
+               <appender name="AUDIT"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
+             <evaluator>        
+               <matcher>
+                 <Name>audit</Name>
+                 <!-- filter out odd numbered statements -->
+                 <regex>co\=aairest</regex>
+               </matcher>        
+               <expression>level == INFO &amp;&amp; audit.matches(formattedMessage)</expression>
+             </evaluator>
+             <OnMatch>ACCEPT</OnMatch>
+             <OnMismatch>DENY</OnMismatch>
+           </filter>
+               <file>${logDirectory}/rest/audit.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/metric.log.%d{yyyy-MM-dd}</fileNamePattern>
+               </rollingPolicy>
+               <encoder>
+                       <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%m%n</pattern>
+               </encoder>
+       </appender>
+       
+       <appender name="auditLogs"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+               </filter>
+               <file>${logDirectory}/rest/audit.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/audit-${lrmRVer}-${lrmRO}-${Pid}.%d{yyyy-MM-dd}.log.zip
+                       </fileNamePattern>
+               </rollingPolicy>
+               <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize>
+               </triggeringPolicy>
+               <encoder>
+                       <pattern>"%d [%thread] %-5level %logger{1024} - %msg%n"</pattern>
+               </encoder>
+       </appender>
+       
+       <appender name="perfLogs"
+               class="ch.qos.logback.core.rolling.RollingFileAppender">
+               <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+               </filter>
+               <file>${logDirectory}/rest/perform.log</file>
+               <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                       <fileNamePattern>${logDirectory}/rest/perform-${lrmRVer}-${lrmRO}-${Pid}.%d{yyyy-MM-dd}.log.zip
+                       </fileNamePattern>
+               </rollingPolicy>
+               <!--  <triggeringPolicy
+                       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+                       <maxFileSize>5MB</maxFileSize>
+               </triggeringPolicy> -->
+               <encoder>
+                       <pattern>"%d [%thread] %-5level %logger{1024} - %msg%n"</pattern>
+               </encoder>
+       </appender>
+
+       <!-- Spring related loggers -->
+       <logger name="org.springframework" level="WARN" />
+       <logger name="org.springframework.beans" level="WARN" />
+       <logger name="org.springframework.web" level="WARN" />
+       <logger name="com.blog.spring.jms" level="WARN" />
+
+       <!-- AJSC Services (bootstrap services) -->
+       <logger name="ajsc" level="WARN" />
+       <logger name="ajsc.RouteMgmtService" level="WARN" />
+       <logger name="ajsc.ComputeService" level="WARN" />
+       <logger name="ajsc.VandelayService" level="WARN" />
+       <logger name="ajsc.FilePersistenceService" level="WARN" />
+       <logger name="ajsc.UserDefinedJarService" level="WARN" />
+       <logger name="ajsc.UserDefinedBeansDefService" level="WARN" />
+       <logger name="ajsc.LoggingConfigurationService" level="WARN" />
+       
+       <!-- AJSC related loggers (DME2 Registration, csi logging, restlet, servlet 
+               logging) -->
+       <logger name="ajsc.utils" level="WARN" />
+       <logger name="ajsc.utils.DME2Helper" level="WARN" />
+       <logger name="ajsc.filters" level="WARN" />
+       <logger name="ajsc.beans.interceptors" level="WARN" />
+       <logger name="ajsc.restlet" level="WARN" />
+       <logger name="ajsc.servlet" level="WARN" />
+       <logger name="com.att.ajsc" level="WARN" />
+       <logger name="com.att.ajsc.csi.logging" level="WARN" />
+       <logger name="com.att.ajsc.filemonitor" level="WARN" />
+
+       <!-- Other Loggers that may help troubleshoot -->
+       <logger name="net.sf" level="WARN" />
+       <logger name="org.apache.commons.httpclient" level="WARN" />
+       <logger name="org.apache.commons" level="WARN" />
+       <logger name="org.apache.coyote" level="WARN" />
+       <logger name="org.apache.jasper" level="WARN" />
+
+       <!-- Camel Related Loggers (including restlet/servlet/jaxrs/cxf logging. 
+               May aid in troubleshooting) -->
+       <logger name="org.apache.camel" level="WARN" />
+       <logger name="org.apache.cxf" level="WARN" />
+       <logger name="org.apache.camel.processor.interceptor" level="WARN" />
+       <logger name="org.apache.cxf.jaxrs.interceptor" level="WARN" />
+       <logger name="org.apache.cxf.service" level="WARN" />
+       <logger name="org.restlet" level="WARN" />
+       <logger name="org.apache.camel.component.restlet" level="WARN" />
+
+       <!-- logback internals logging -->
+       <logger name="ch.qos.logback.classic" level="INFO" />
+       <logger name="ch.qos.logback.core" level="INFO" />
+
+       <!-- logback jms appenders & loggers definition starts here -->
+
+       <if condition='property("JMS_BROKER").contains("WMQ")'>
+               <then>
+                       <appender name="Audit-Record-Queue" class="ajsc.JMSQueueAppender">
+                               <param name="InitialContextFactoryName" value="${JMS_WMQ_INITIAL_CONNECTION_FACTORY_NAME}" />
+                               <param name="ProviderURL" value="${JMS_WMQ_PROVIDER_URL}" />
+                               <param name="DestinationName" value="${JMS_WMQ_AUDIT_DESTINATION_NAME}" />
+                               <param name="ConnectionFactoryName" value="${JMS_WMQ_CONNECTION_FACTORY_NAME}" />
+                       </appender>
+                       <appender name="Performance-Tracker-Queue" class="ajsc.JMSQueueAppender">
+                               <param name="InitialContextFactoryName" value="${JMS_WMQ_INITIAL_CONNECTION_FACTORY_NAME}" />
+                               <param name="ProviderURL" value="${JMS_WMQ_PROVIDER_URL}" />
+                               <param name="DestinationName" value="${JMS_WMQ_PERF_DESTINATION_NAME}" />
+                               <param name="ConnectionFactoryName" value="${JMS_WMQ_CONNECTION_FACTORY_NAME}" />
+                       </appender>
+               </then>
+               <else> <!-- logback jms appenders definition starts here -->
+                       <appender name="Audit-Record-Queue" class="ajsc.JMSQueueAppender">
+                               <param name="InitialContextFactoryName"
+                                       value="com.tibco.tibjms.naming.TibjmsInitialContextFactory" />
+                               <param name="ProviderURL" value="${JMS_TIBCO_PROVIDER_URL}" />
+                               <param name="userName" value="${JMS_LOGGER_USER_NAME}" />
+                               <param name="password" value="${JMS_LOGGER_PASSWORD}" />
+                               <QueueBindingName>${JMS_LOGGER_AUDIT_QUEUE_BINDING}
+                               </QueueBindingName>
+                       </appender>
+                       <appender name="Performance-Tracker-Queue" class="ajsc.JMSQueueAppender">
+                               <param name="InitialContextFactoryName"
+                                       value="com.tibco.tibjms.naming.TibjmsInitialContextFactory" />
+                               <param name="ProviderURL" value="${JMS_TIBCO_PROVIDER_URL}" />
+                               <param name="userName" value="${JMS_LOGGER_USER_NAME}" />
+                               <param name="password" value="${JMS_LOGGER_PASSWORD}" />
+                               <QueueBindingName>${JMS_LOGGER_PERF_QUEUE_BINDING}
+                               </QueueBindingName>
+                       </appender>
+               </else>
+       </if>
+       
+       <appender name="ASYNC-audit" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>1000</queueSize>
+               <discardingThreshold>0</discardingThreshold>
+               <appender-ref ref="Audit-Record-Queue" />
+       </appender>
+       
+       <appender name="ASYNC-perf" class="ch.qos.logback.classic.AsyncAppender">
+               <queueSize>1000</queueSize>
+               <discardingThreshold>0</discardingThreshold>
+               <appender-ref ref="Performance-Tracker-Queue" />
+       </appender>
+
+       <!--  
+       <logger name="AuditRecord" level="INFO" additivity="FALSE">
+               <appender-ref ref="ASYNC-audit" />
+               <appender-ref ref="auditLogs" />
+       </logger>
+       <logger name="AuditRecord_DirectCall" level="INFO" additivity="FALSE">
+               <appender-ref ref="ASYNC-audit" />
+               <appender-ref ref="auditLogs" />
+       </logger>
+       <logger name="PerfTrackerRecord" level="INFO" additivity="FALSE">
+               <appender-ref ref="ASYNC-perf" />
+               <appender-ref ref="perfLogs" />
+       </logger>       
+       -->
+               
+       <logger name="org.openecomp.aai" level="INFO" />
+       
+       <!--
+       <logger name="org.openecomp.aai.util" level="WARN" />
+       <logger name="org.openecomp.aai.rest" level="WARN" />
+       <logger name="org.openecomp.aai.rest.Business" level="WARN" />
+        -->
+       
+       <logger name="org.apache" level="WARN" />
+       <logger name="org.zookeeper" level="WARN" />
+       <logger name="com.thinkaurelius" level="WARN" />
+
+       <root level="WARN">
+               <appender-ref ref="DEBUG" />
+               <appender-ref ref="ERROR" />
+               <appender-ref ref="METRIC" />
+               <appender-ref ref="AUDIT" />
+       </root>
+
+</configuration>
diff --git a/aai-traversal/src/test/resources/maputils/testcases/TestCase1.json b/aai-traversal/src/test/resources/maputils/testcases/TestCase1.json
new file mode 100644 (file)
index 0000000..1f7a794
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "input": {
+    "myImage": {
+      "imageId": "test-imageId-1",
+      "imageName": "test-image-name",
+      "imageList": [
+        {
+          "imageListName": "testListName",
+          "imageListId": "testListId",
+          "imageListNumber": 200,
+          "imageListBoolean": true,
+          "imageListNull": null
+        }
+      ]
+    }
+  },
+  "output": {
+    "my-image": {
+      "image-id": "test-imageId-1",
+      "image-name": "test-image-name",
+      "image-list": [
+        {
+          "image-list-name": "testListName",
+          "image-list-id": "testListId",
+          "image-list-number": 200,
+          "image-list-boolean": true,
+          "image-list-null": null
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/aai-traversal/src/test/resources/maputils/testcases/TestCase2.json b/aai-traversal/src/test/resources/maputils/testcases/TestCase2.json
new file mode 100644 (file)
index 0000000..9b8a1e3
--- /dev/null
@@ -0,0 +1,40 @@
+{
+  "input": {
+    "myImage": {
+      "imageId": "test-imageId-1",
+      "imageName": "test-image-name",
+      "imageList": [
+        {
+          "imageListName": "testListName",
+          "imageListId": "testListId",
+          "imageArray": [
+            [
+              {
+                "imageNestedArrayElement": "value"
+              }
+            ]
+          ]
+        }
+      ]
+    }
+  },
+  "output": {
+    "my-image": {
+      "image-id": "test-imageId-1",
+      "image-name": "test-image-name",
+      "image-list": [
+        {
+          "image-list-name": "testListName",
+          "image-list-id": "testListId",
+          "image-array": [
+            [
+              {
+                "image-nested-array-element": "value"
+              }
+            ]
+          ]
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/aai-traversal/src/test/resources/test_aaiconfig.properties b/aai-traversal/src/test/resources/test_aaiconfig.properties
new file mode 100644 (file)
index 0000000..0af948a
--- /dev/null
@@ -0,0 +1,97 @@
+###
+# ============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=========================================================
+###
+
+####################################################################
+#  REMEMBER TO THINK ABOUT ENVIRONMENTAL DIFFERENCES AND CHANGE THE
+#  TEMPLATE AND *ALL* DATAFILES
+####################################################################
+
+aai.config.checktime=1000
+
+# this could come from siteconfig.pl?
+aai.config.nodename=AutomaticallyOverwritten
+
+aai.logging.hbase.interceptor=true
+aai.logging.hbase.enabled=true
+aai.logging.hbase.logrequest=true
+aai.logging.hbase.logresponse=true
+
+aai.logging.trace.enabled=true
+aai.logging.trace.logrequest=false
+aai.logging.trace.logresponse=false
+
+aai.auth.cspcookies_on=false
+aai.dbmodel.filename=ex5.json
+
+aai.server.url.base=https://localhost:8446/aai/
+aai.server.url=https://localhost:8446/aai/v10/
+
+aai.truststore.filename=aai_keystore
+aai.truststore.passwd.x=
+aai.keystore.filename=aai-client-cert.p12
+aai.keystore.passwd.x=
+
+# the following parameters are not reloaded automatically and require a manual bounce
+storage.backend=hbase
+storage.hostname=ONAPserverTBD
+#schema.default=none
+storage.lock.wait-time=300
+storage.hbase.table=aaigraph-dev1.dev
+storage.hbase.ext.zookeeper.znode.parent=/hbase-unsecure
+# Setting db-cache to false ensure the fastest propagation of changes across servers
+cache.db-cache = false
+#cache.db-cache-clean-wait = 20
+#cache.db-cache-time = 180000
+#cache.db-cache-size = 0.5
+
+# for transaction log
+hbase.table.name=aailogging-dev1.dev
+hbase.notificationTable.name=aainotification-dev1.dev
+hbase.table.timestamp.format=YYYYMMdd-HH:mm:ss:SSS
+hbase.zookeeper.quorum=ONAPserverTBD
+hbase.zookeeper.property.clientPort=2181
+hbase.zookeeper.znode.parent=/hbase-unsecure
+
+# single primary server
+aai.primary.filetransfer.serverlist=ONAPserverTBD
+aai.primary.filetransfer.primarycheck=echo:8443/aai/util/echo
+aai.primary.filetransfer.pingtimeout=5000
+aai.primary.filetransfer.pingcount=5
+
+#rsync properties
+aai.rsync.command=rsync
+aai.rsync.options.list=-v|-t
+aai.rsync.remote.user=aaiadmin
+aai.rsync.enabled=y
+
+aai.notification.current.version=v10
+aai.notificationEvent.default.status=UNPROCESSED
+aai.notificationEvent.default.eventType=AAI-EVENT
+aai.notificationEvent.default.domain=devINT1
+aai.notificationEvent.default.sourceName=aai
+aai.notificationEvent.default.sequenceNumber=0
+aai.notificationEvent.default.severity=NORMAL
+aai.notificationEvent.default.version=v9
+# This one lets us enable/disable resource-version checking on updates/deletes
+aai.resourceversion.enableflag=true
+aai.logging.maxStackTraceEntries=10
+aai.default.api.version=v10
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644 (file)
index 0000000..7bbe2f2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,312 @@
+<?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">
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <artifactId>ajsc-archetype-parent</artifactId>
+               <groupId>com.att.ajsc</groupId>
+               <version>2.1.0</version>
+       </parent>
+       <groupId>org.openecomp.aai</groupId>
+       <artifactId>traversal</artifactId>
+       <version>1.1.0-SNAPSHOT</version>
+       <name>traversal</name>
+       <packaging>pom</packaging>
+       <modules>
+               <module>aai-traversal</module>
+       </modules>
+       <properties>
+               <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+               <maven.compiler.target>1.8</maven.compiler.target>
+               <maven.compiler.source>1.8</maven.compiler.source>
+               <module.ajsc.namespace.name>ActiveAndAvailableInventory-Traversal</module.ajsc.namespace.name>
+               <module.ajsc.namespace.version>v1</module.ajsc.namespace.version>
+               <ajscRuntimeVersion>5.0.0-RC16.0.5</ajscRuntimeVersion>
+               <aai-schema.version>1.1.0-SNAPSHOT</aai-schema.version>
+               <aai.project.version>${project.version}</aai.project.version>
+
+               <!-- This will be the Absolute Root of the Project and should contain NO 
+                       Versioning -->
+               <absoluteDistFilesRoot>/opt/app/aai-traversal</absoluteDistFilesRoot>
+
+               <!-- For Versioning upon installation, add /${project.version} to distFilesRoot. 
+                       For NO Versioning, leave as is -->
+               <!-- example: /appl/${project.artifactId}/${project.version}. Also, add 
+                       ${project.version} to ${runAjscHome} for running locally. -->
+               <distFilesRoot>/opt/app/${project.artifactId}</distFilesRoot>
+               <!-- <distFilesRoot>/opt/app/traversal/${project.version}</distFilesRoot> -->
+               <aaiAppHome>${basedir}</aaiAppHome>
+               <runAjscHome>${aaiAppHome}/target/swm/package/nix/dist_files${distFilesRoot}</runAjscHome>
+               <!-- For SOA Cloud Installation -->
+               <installOwnerUser>aaiadmin</installOwnerUser>
+               <installOwnerGroup>aaiadmin</installOwnerGroup>
+               <ownerManagementGroup>org.openecomp.aai.dev</ownerManagementGroup>
+
+               <!-- Port Selection. A value of 0 will allow for dynamic port selection. 
+                       For local testing, you may choose to hardcode this value to something like 
+                       8080 -->
+               <serverPort>8083</serverPort>
+               <sslport>8446</sslport>
+               <testRouteOffer>workstation</testRouteOffer>
+               <testEnv>DEV</testEnv>
+
+               <!-- For using CXF with Maven -->
+               <cxf.version>3.0.4</cxf.version>
+               <swmpkgversion>0.0.1</swmpkgversion>
+               <snapshot.file>int1-data.graphson</snapshot.file>
+               <aai-core.version>1.1.0-SNAPSHOT</aai-core.version>
+       </properties>
+
+       <!-- The standard build tasks for this project are inherited from the parent. 
+               Please do not override the build tasks. However tasks and/or profiles can 
+               be included here as well as additional dependencies for your service. Any 
+               runtime or compile scope dependencies will be copied to the INSTALLATION_PATH/extJars 
+               folder and will be made available on the AJSC classpath for your service. 
+               Please, NOTE: DME2 and CSM related dependencies are EXTERNALIZED within the 
+               CSI environment. Therefore, they are provided within this project as "provided" 
+               dependencies. In order for the AJSC to run properly, locally, the CSM and 
+               DME2 dependencies will be copied into the target/commonLibs folder and will 
+               be made available to the classpath of the AJSC through the use of the system 
+               property, "AJSC_EXTERNAL_LIB_FOLDERS". This system property needs to be set 
+               in the "runAjsc" maven profile within the pom.xml (and, is defaulted to do 
+               so). If you have a startup failure related to a missing dme2 class not found 
+               exception, please contact the AJSC team for assistance.--> 
+       <dependencies>
+               <dependency>
+                       <groupId>csi-schemas-source</groupId>
+                       <artifactId>cmn-CommonDataModel</artifactId>
+                       <version>100.0.145</version>
+               </dependency>
+       </dependencies>
+       <profiles>
+               <profile>
+                       <id>jenkins-properties</id>
+                       <activation>
+                               <os>
+                                       <family>unix</family>
+                               </os>
+                       </activation>
+                       <properties>
+                               <swmpkgversion>${env.swmpkgversion}</swmpkgversion>
+                       </properties>
+               </profile>
+               <profile>
+                       <id>runAjsc</id>
+                       <build>
+                               <defaultGoal>initialize</defaultGoal>
+                               <plugins>
+
+                                       <plugin>
+                                               <groupId>org.codehaus.mojo</groupId>
+                                               <artifactId>exec-maven-plugin</artifactId>
+                                               <version>1.3.2</version>
+                                               <executions>
+                                                       <execution>
+                                                               <id>run ajsc</id>
+                                                               <phase>initialize</phase>
+                                                               <goals>
+                                                                       <goal>java</goal>
+                                                               </goals>
+                                                               <configuration>
+                                                                       <!-- In order to better mimic a SOA cloud installation of AJSC (and 
+                                                                               to help eliminate Maven/Eclipse/AJSC classpath issues that may be difficult 
+                                                                               to diagnose), within this profile used to run locally, we are NOT including 
+                                                                               project dependencies. These will be loaded by AJSC from $AJSC_HOME/extJars. 
+                                                                               The only jar needed to run AJSC is the ajsc-runner.jar, and therefore is 
+                                                                               the only dependency required by this profile to run locally. -->
+                                                                       <includeProjectDependencies>false</includeProjectDependencies>
+                                                                       <includePluginDependencies>true</includePluginDependencies>
+                                                                       <executable>java</executable>
+                                                                       <mainClass>com.att.ajsc.runner.Runner</mainClass>
+                                                                       <executableDependency>
+                                                                               <groupId>com.att.ajsc</groupId>
+                                                                               <artifactId>ajsc-runner</artifactId>
+                                                                       </executableDependency>
+
+                                                                       <environmentVariables>
+                                                                               <AJSC_HOME>${runAjscHome}</AJSC_HOME>
+                                                                       </environmentVariables>
+                                                                       <additionalClasspathElements>
+                                                                               <additionalClasspathElement>${runAjscHome}/extJars/logback-access-1.1.7.jar</additionalClasspathElement>
+                                                                               <additionalClasspathElement>${runAjscHome}/extJars/logback-core-1.1.7.jar</additionalClasspathElement>
+                                                                               <additionalClasspathElement>${runAjscHome}/extJars/aai-core-${aai-core.version}.jar</additionalClasspathElement>
+                                                                       </additionalClasspathElements>
+
+                                                                       <!-- Main AJSC System Properties below (necessary for proper startup) -->
+                                                                       <systemProperties>
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_HOME</key>
+                                                                                       <value>${runAjscHome}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>AFT_HOME</key>
+                                                                                       <value>${runAjscHome}/bundleconfig/</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_CONF_HOME</key>
+                                                                                       <value>${aaiAppHome}/bundleconfig-local</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>logback.configurationFile</key>
+                                                                                       <value>${aaiAppHome}/ajsc-shared-config/etc/logback.xml</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_SHARED_CONFIG</key>
+                                                                                       <value>${aaiAppHome}/ajsc-shared-config</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>file.separator</key>
+                                                                                       <value>/</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>snapshot.location</key>
+                                                                                       <value>${basedir}/ajsc-aai/snapshots/${snapshot.file}</value>
+                                                                               </systemProperty>
+                                                                               <!-- Please, NOTE: The following 2 system properties will normally 
+                                                                                       be set within the sys-props.properties file once deployed to a node. We are 
+                                                                                       setting them HERE to run locally to make more efficient use of maven variable 
+                                                                                       replacement for ${basedir} -->
+                                                                               <!-- AJSC_EXTERNAL_LIB_FOLDERS represents the particular jars that 
+                                                                                       will be externalized on a CSI node. This includes dme2 and csm related artifact. -->
+                                                                               <sysproperty>
+                                                                                       <key>AJSC_EXTERNAL_LIB_FOLDERS</key>
+                                                                                       <value>${aaiAppHome}/target/commonLibs</value>
+                                                                               </sysproperty>
+                                                                               <!-- AJSC_EXTERNAL_PROPERTIES_FOLDERS represents the particular 
+                                                                                       files that may need to be added to the classpath. These files will be externalized 
+                                                                                       on a CSI node. This includes dme2 and csm related artifact (such as csm-config-app.properties). 
+                                                                                       Failure to have these files on the classpath may result in errors thrown 
+                                                                                       by csm framework. -->
+                                                                               <sysproperty>
+                                                                                       <key>AJSC_EXTERNAL_PROPERTIES_FOLDERS</key>
+                                                                                       <value>${aaiAppHome}/ajsc-shared-config/etc</value>
+                                                                               </sysproperty>
+
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_SERVICE_NAMESPACE</key>
+                                                                                       <value>${module.ajsc.namespace.name}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>AJSC_SERVICE_VERSION</key>
+                                                                                       <value>${module.ajsc.namespace.version}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>SOACLOUD_SERVICE_VERSION</key>
+                                                                                       <value>${project.version}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>server.port</key>
+                                                                                       <value>${serverPort}</value>
+                                                                               </systemProperty>
+                                                                               <systemProperty>
+                                                                                       <key>aai-core.version</key>
+                                                                                       <value>${aai-core.version}</value>
+                                                                               </systemProperty>
+                                                                       </systemProperties>
+
+                                                                       <!-- Command Line Arguments to add to the java command. Here, you 
+                                                                               can specify the port as well as the Context you want your service to run 
+                                                                               in. Use context=/ to run in an unnamed Context (Root Context). The default 
+                                                                               configuration of the AJSC is to run under the / Context. Setting the port 
+                                                                               here can aid during the development phase of your service. However, you can 
+                                                                               leave this argument out entirely, and the AJSC will default to using an Ephemeral 
+                                                                               port. -->
+                                                                       <arguments>
+                                                                               <argument>context=/</argument>
+                                                                               <argument>port=${serverPort}</argument>
+                                                                               <argument>sslport=${sslport}</argument>
+                                                                       </arguments>
+                                                               </configuration>
+                                                       </execution>
+                                               </executions>
+                                               <configuration>
+                                                       <executable>java</executable>
+                                               </configuration>
+                                               <dependencies>
+                                                       <dependency>
+                                                               <groupId>com.att.ajsc</groupId>
+                                                               <artifactId>ajsc-runner</artifactId>
+                                                               <version>${ajscRuntimeVersion}</version>
+                                                       </dependency>
+                                               </dependencies>
+                                       </plugin>
+                               </plugins>
+                       </build>
+               </profile>
+       </profiles>
+<build>
+       <pluginManagement>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <version>3.1</version>
+                               <configuration>
+                                       <compilerId>groovy-eclipse-compiler</compilerId>
+                                       <verbose>false</verbose>
+                                       <source>1.8</source>
+                                       <target>1.8</target>
+                               </configuration>
+                               <dependencies>
+                                       <dependency>
+                                               <groupId>org.codehaus.groovy</groupId>
+                                               <artifactId>groovy-eclipse-compiler</artifactId>
+                                               <version>2.9.0-01</version>
+                                       </dependency>
+                                       <dependency>
+                                               <groupId>org.codehaus.groovy</groupId>
+                                               <artifactId>groovy-eclipse-batch</artifactId>
+                                               <version>2.3.4-01</version>
+                                       </dependency>
+                               </dependencies>
+                       </plugin>
+               </plugins>
+       </pluginManagement>
+                   <plugins>
+            <!-- license plugin -->
+                   <plugin>
+                   <groupId>org.codehaus.mojo</groupId>
+                   <artifactId>license-maven-plugin</artifactId>
+                   <version>1.12</version>
+                   <configuration>
+                       <addJavaLicenseAfterPackage>false</addJavaLicenseAfterPackage>
+                       <licenseName>apache_v2</licenseName>
+                       <inceptionYear>2017</inceptionYear>
+                       <organizationName>AT&amp;T Intellectual Property. All rights reserved.</organizationName>
+                       <projectName>org.openecomp.aai</projectName>
+                       <canUpdateCopyright>true</canUpdateCopyright>
+                       <canUpdateDescription>true</canUpdateDescription>
+                       <canUpdateLicense>true</canUpdateLicense>
+                       <emptyLineAfterHeader>true</emptyLineAfterHeader>
+                       <processStartTag>============LICENSE_START=======================================================</processStartTag>
+                       <processEndTag>============LICENSE_END=========================================================</processEndTag>
+                       <sectionDelimiter>================================================================================</sectionDelimiter>
+                       <includes>
+                               <include>**/*.java</include>
+                               <include>**/*.ksh</include>
+                               <include>**/*.sh</include>
+                               <include>**/*.ftl</include>
+                               <include>**/*.xsd</include>
+                               <include>**/*.xjb</include>
+                               <include>**/*.yml</include>
+                               <include>**/*.yaml</include>
+                               <include>**/aai*.xml</include>
+                               <include>**/*logback*.xml</include>
+                               <include>**/*aaiconfig*.properties</include>
+                               <include>**/*titan*.properties</include>
+                       </includes>
+                       </configuration>
+                   <executions>
+                       <execution>
+                            <id>first</id>
+                             <goals>
+                                 <goal>update-file-header</goal>
+                             </goals>
+                                 <phase>process-sources</phase>
+                        </execution>
+                     </executions>
+                  </plugin>
+              </plugins>
+       </build>
+       
+</project>
diff --git a/set-debug-port.bat b/set-debug-port.bat
new file mode 100644 (file)
index 0000000..86d18bf
--- /dev/null
@@ -0,0 +1 @@
+SET MAVEN_OPTS=-Xms2048m -Xmx2048m -Xdebug -Xnoagent -Djava.compile=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9446
\ No newline at end of file
diff --git a/start-cassandra-service.bat b/start-cassandra-service.bat
new file mode 100644 (file)
index 0000000..8b7b9ea
--- /dev/null
@@ -0,0 +1,33 @@
+@echo off
+
+:: BatchGotAdmin
+:-------------------------------------
+REM  --> Check for permissions
+    IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (
+>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system"
+) ELSE (
+>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
+)
+
+REM --> If error flag set, we do not have admin.
+if '%errorlevel%' NEQ '0' (
+    echo Requesting administrative privileges...
+    goto UACPrompt
+) else ( goto gotAdmin )
+
+:UACPrompt
+    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
+    set params = %*:"=""
+    echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"
+
+    "%temp%\getadmin.vbs"
+    del "%temp%\getadmin.vbs"
+    exit /B
+
+:gotAdmin
+    pushd "%CD%"
+    CD /D "%~dp0"
+:--------------------------------------    
+call net start DataStax_Cassandra_Community_Server
+call net start DataStax_OpsCenter_Agent
+call net start DataStax_OpsCenter_Community
\ No newline at end of file
diff --git a/stop-cassandra-service.bat b/stop-cassandra-service.bat
new file mode 100644 (file)
index 0000000..32335ba
--- /dev/null
@@ -0,0 +1,33 @@
+@echo off
+
+:: BatchGotAdmin
+:-------------------------------------
+REM  --> Check for permissions
+    IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (
+>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system"
+) ELSE (
+>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
+)
+
+REM --> If error flag set, we do not have admin.
+if '%errorlevel%' NEQ '0' (
+    echo Requesting administrative privileges...
+    goto UACPrompt
+) else ( goto gotAdmin )
+
+:UACPrompt
+    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
+    set params = %*:"=""
+    echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"
+
+    "%temp%\getadmin.vbs"
+    del "%temp%\getadmin.vbs"
+    exit /B
+
+:gotAdmin
+    pushd "%CD%"
+    CD /D "%~dp0"
+:--------------------------------------    
+call net stop DataStax_Cassandra_Community_Server
+call net stop DataStax_OpsCenter_Agent
+call net stop DataStax_OpsCenter_Community
\ No newline at end of file
diff --git a/test_csvWriter.csv b/test_csvWriter.csv
new file mode 100644 (file)
index 0000000..2f66fec
--- /dev/null
@@ -0,0 +1,2 @@
+s0,s1
+t0,t1
diff --git a/version.properties b/version.properties
new file mode 100644 (file)
index 0000000..abe15cf
--- /dev/null
@@ -0,0 +1,14 @@
+###########################################################
+# Versioning variables
+# Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... )
+# because they are used in Jenkins, whose plug-in doesn't support
+
+major_version=1
+minor_version=1
+patch_version=0
+
+base_version=${major_version}.${minor_version}.${patch_version}
+
+# Release must be completed with GIT information # in Jenkins
+release_version=${base_version}
+snapshot_version=${base_version}-SNAPSHOT
\ No newline at end of file