From: Prudence Au Date: Fri, 20 Jul 2018 02:49:52 +0000 (-0400) Subject: Initial submission for validation service X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=7a02a56a976f80d6968ef8737c2bb9ad6281f0c3;p=aai%2Fvalidation.git Initial submission for validation service Change-Id: Iec8515149f4619c82964e9e979911eaeb2491513 Issue-ID: LOG-427 Signed-off-by: Prudence Au --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..06cbf9e --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +logs/ +debug-logs/ +bundleconfig-local/etc/auth/tomcat_keystore +.classpath +.project +.settings/ +target/ diff --git a/.gitreview b/.gitreview new file mode 100644 index 0000000..fbb8dfa --- /dev/null +++ b/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=gerrit.onap.org +port=29418 +project=aai/validation.git diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..7e1043b --- /dev/null +++ b/README.MD @@ -0,0 +1,22 @@ +# Validation microservice + +This project has mixed Java and Groovy source code. + +[Maven](https://maven.apache.org/) 3+ is required. + +#### To build and run tests: +`mvn clean verify` + +Eclipse users should install [Groovy Eclipse plugins](https://github.com/groovy/groovy-eclipse/wiki). + +#### To generate jars (including apidocs): +`mvn package` + +#### To run on localhost: +`mvn spring-boot:run` + +### HTTPS interfaces + +[Validation Service](https://localhost:9501/services/validation-service/v1/app/validate) + +[Info Service](https://localhost:9501/services/validation-service/v1/core/core-service/info) diff --git a/appconfig-local/aai-environment.properties b/appconfig-local/aai-environment.properties new file mode 100644 index 0000000..0b40e15 --- /dev/null +++ b/appconfig-local/aai-environment.properties @@ -0,0 +1,31 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +host=10.147.138.163 +port=8443 +httpProtocol=https +trustStorePath=/auth/tomcat_keystore +#trustStorePassword intentionally left blank +trustStorePassword.x= +keyStorePath=/auth/aai-client-cert.p12 +keyStorePassword.x=dfcfd1003bdde18de8efea3c8661510e +keyManagerFactoryAlgorithm=SunX509 +keyStoreType=PKCS12 +securityProtocol=TLS +connectionTimeout=5000 +readTimeout=1000 + +baseModelURI=/aai/v8/service-design-and-creation/models/model diff --git a/appconfig-local/auth/auth_policy.json b/appconfig-local/auth/auth_policy.json new file mode 100644 index 0000000..dacbf04 --- /dev/null +++ b/appconfig-local/auth/auth_policy.json @@ -0,0 +1,46 @@ +{"roles": [ + { + "name": "admin", + "functions": [ + { + "name": "actions", + "methods": [ + {"name": "GET"}, + {"name": "DELETE"}, + {"name": "PUT"} + ] + }, + { + "name": "validate", + "methods": [{"name": "POST"}] + } + ], + "users": [ + {"username": "CN=common-name, OU=org-unit, O=org, L=location, ST=state, C=US"}, + {"username": "CN=test, OU=qa, O=Test Ltd, L=London, ST=London, C=GB"}, + {"username": "CN=aai-client.dev.att.com, OU=aai digicert client dev, O=\"AT&T Services, Inc.\", L=Dallas, ST=Texas, C=US"} + ] + }, + { + "name": "ops", + "functions": [{ + "name": "actions", + "methods": [{"name": "POST"}] + }], + "users": [ + {"username": "CN=common-name, OU=org-unit, O=org, L=location, ST=state, C=US"}, + {"username": "CN=test, OU=qa, O=Test Ltd, L=London, ST=London, C=GB"} + ] + }, + { + "name": "basicauth", + "functions": [{ + "name": "util", + "methods": [{"name": "GET"}] + }], + "users": [{ + "user": "aai", + "pass": "OBF:1u2a1t2v1vgb1s3g1s3m1vgj1t3b1u30" + }] + } +]} \ No newline at end of file diff --git a/appconfig-local/auth/tomcat_keystore b/appconfig-local/auth/tomcat_keystore new file mode 100644 index 0000000..cbec390 Binary files /dev/null and b/appconfig-local/auth/tomcat_keystore differ diff --git a/appconfig-local/rule-indexing.properties b/appconfig-local/rule-indexing.properties new file mode 100644 index 0000000..447480f --- /dev/null +++ b/appconfig-local/rule-indexing.properties @@ -0,0 +1,20 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +rule.indexing.events=POA-EVENT +rule.indexing.exclude.oxm.validation=POA-EVENT +rule.indexing.key.attributes=$.poa-event.modelVersionId,$.poa-event.modelInvariantId +rule.indexing.default.key=default-rules diff --git a/appconfig-local/schemaIngest.properties b/appconfig-local/schemaIngest.properties new file mode 100644 index 0000000..aeec308 --- /dev/null +++ b/appconfig-local/schemaIngest.properties @@ -0,0 +1,23 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +# Properties for the SchemaLocationsBean +# The AAI Schema jar will be unpacked to bundleconfig/etc +schemaConfig=bundleconfig +# Files named aai_oxm_v*.xml are unpacked here: +nodeDir=${AJSC_HOME}/bundleconfig/etc/oxm +# Dummy folder/directory: +edgeDir=${AJSC_HOME}/bundleconfig/etc/oxm diff --git a/appconfig-local/topics/topic-poa-audit-result.properties b/appconfig-local/topics/topic-poa-audit-result.properties new file mode 100644 index 0000000..3c70ede --- /dev/null +++ b/appconfig-local/topics/topic-poa-audit-result.properties @@ -0,0 +1,22 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +poa-audit-result.name=POA-AUDIT-RESULT +poa-audit-result.host=10.147.57.135:3904 +poa-audit-result.publisher.partition=1 +poa-audit-result.username= +poa-audit-result.password= +poa-audit-result.transport.type=HTTPAUTH \ No newline at end of file diff --git a/appconfig-local/topics/topic-poa-rule-validation.properties b/appconfig-local/topics/topic-poa-rule-validation.properties new file mode 100644 index 0000000..cf8740b --- /dev/null +++ b/appconfig-local/topics/topic-poa-rule-validation.properties @@ -0,0 +1,23 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +poa-rule-validation.name=POA-RULE-VALIDATION +poa-rule-validation.host=10.147.57.135:3904 +poa-rule-validation.username= +poa-rule-validation.password= +poa-rule-validation.consumer.group=poa-validator +poa-rule-validation.consumer.id=0 +poa-rule-validation.transport.type=HTTPAUTH \ No newline at end of file diff --git a/appconfig-local/validation-service-auth.properties b/appconfig-local/validation-service-auth.properties new file mode 100644 index 0000000..d717c93 --- /dev/null +++ b/appconfig-local/validation-service-auth.properties @@ -0,0 +1,18 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +auth.policy.file=appconfig-local/auth/auth_policy.json +auth.authentication.disable=false \ No newline at end of file diff --git a/appconfig-local/validation-service.properties b/appconfig-local/validation-service.properties new file mode 100644 index 0000000..3d501da --- /dev/null +++ b/appconfig-local/validation-service.properties @@ -0,0 +1,29 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +topic.publish.enable=true +topic.publish.retries=3 +topic.consume.enable=true +topic.consume.polling.interval.seconds=3 + +event.domain=spock +event.action.exclude=DELETE +event.type.rule=AAI-EVENT,AAI-DATA-EXPORT-API,GIZMO-EVENT,POA-EVENT +event.type.model=AAI-DATA-EXPORT-NQ +event.type.end=END-EVENT + +model.cache.expirySeconds=3 +aai.oxm.version=12 diff --git a/bundleconfig/etc/appprops/model-instance-mapping.json_conf b/bundleconfig/etc/appprops/model-instance-mapping.json_conf new file mode 100644 index 0000000..eba525a --- /dev/null +++ b/bundleconfig/etc/appprops/model-instance-mapping.json_conf @@ -0,0 +1,18 @@ +[ + { + "mappingType": "RELATIONSHIP", + "model": { + "root": "model-elements/model-element", + "id": "relationship-list/relationship/relationship-data/relationship-value[../relationship-key/text()='model.model-name-version-id']", + "value": "relationship-list/relationship/related-to-property/property-value[../property-key/text()='model.model-name']", + "filter": { + "path": "relationship-list/relationship/related-to-property/property-value[../property-key/text()='model.model-type']", + "valid": ["widget"] + } + }, + "instance": { + "origin": "$.inventory-response-item[0]", + "root": "$.inventory-response-items.inventory-response-item[*]" + } + } +] diff --git a/bundleconfig/etc/oxm/aai_oxm_cloud_v12.xml b/bundleconfig/etc/oxm/aai_oxm_cloud_v12.xml new file mode 100644 index 0000000..99a7850 --- /dev/null +++ b/bundleconfig/etc/oxm/aai_oxm_cloud_v12.xml @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundleconfig/etc/oxm/aai_oxm_v10.xml b/bundleconfig/etc/oxm/aai_oxm_v10.xml new file mode 100644 index 0000000..3928106 --- /dev/null +++ b/bundleconfig/etc/oxm/aai_oxm_v10.xml @@ -0,0 +1,6570 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundleconfig/etc/oxm/aai_oxm_v8.xml b/bundleconfig/etc/oxm/aai_oxm_v8.xml new file mode 100644 index 0000000..1467453 --- /dev/null +++ b/bundleconfig/etc/oxm/aai_oxm_v8.xml @@ -0,0 +1,4363 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundleconfig/etc/oxm/aai_oxm_v9.xml b/bundleconfig/etc/oxm/aai_oxm_v9.xml new file mode 100644 index 0000000..2c8bc9e --- /dev/null +++ b/bundleconfig/etc/oxm/aai_oxm_v9.xml @@ -0,0 +1,4773 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundleconfig/etc/oxm/aai_oxm_without_cloud_v12.xml b/bundleconfig/etc/oxm/aai_oxm_without_cloud_v12.xml new file mode 100644 index 0000000..e68e157 --- /dev/null +++ b/bundleconfig/etc/oxm/aai_oxm_without_cloud_v12.xml @@ -0,0 +1,5773 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundleconfig/etc/rules/aai-event/common_rules.groovy b/bundleconfig/etc/rules/aai-event/common_rules.groovy new file mode 100644 index 0000000..70980fe --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/common_rules.groovy @@ -0,0 +1,69 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +rule { + name 'prov-status' + category 'INVALID_VALUE' + description 'prov-status value restricted to one of PREPROV, NVTPROV, PROV, CAPPED, DECOM, RETIRED' + errorText 'Invalid prov-status value. Must be PREPROV, NVTPROV, PROV, CAPPED, DECOM, or RETIRED' + severity 'CRITICAL' + attributes 'status' + validate '''switch (status) { + case "PREPROV": + case "NVTPROV": + case "PROV": + case "CAPPED": + case "DECOM": + case "RETIRED": + return true + default: return false + }''' +} + +// The following are used by both vce and newvce + +rule { + name 'vnf-name' + category 'INVALID_NAME' + description 'Invalid naming convention' + errorText 'Invalid name - attribute does not match xxxxxnnnvbc (where x = alphanumeric and n = numeric)' + severity 'MINOR' + attributes 'name' + validate 'name != null && name.matches("[a-z,0-9]{5}[0-9]{3}vbc")' +} + +rule { + name 'vnf-type' + category 'INVALID_VALUE' + description 'Invalid value' + errorText 'Invalid value - attribute must equal esx-vce' + severity 'MINOR' + attributes 'name' + validate 'name != null && name.matches("esx-vce")' +} + +rule { + name 'heat-stack-id equals first 11 bytes of vnf-name' + category 'INVALID_VALUE' + description 'The value of heat-stack-id must equal the first 11 bytes of vnf-name' + errorText 'Invalid value - the value of heat-stack-id must equal the first 11 bytes of vnf-name' + severity 'MINOR' + attributes 'heatstackid', 'vnfname' + validate '''def firstEleven = { str -> str ? str.take(11) : null } + heatstackid.equals(firstEleven(vnfname))''' +} diff --git a/bundleconfig/etc/rules/aai-event/entity-availability-zone.groovy b/bundleconfig/etc/rules/aai-event/entity-availability-zone.groovy new file mode 100644 index 0000000..8fdec4f --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-availability-zone.groovy @@ -0,0 +1,111 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'availability-zone' + validation { + useRule { + name 'availability-zone name matches naming convention' + attributes 'availability-zone-name' + } + useRule { + name 'hypervisor-type matches naming convention' + attributes 'hypervisor-type' + } + useRule { + name 'operational-state must be operationalState' + attributes 'operational-state' + } + useRule { name 'availability zone is related to dvs-switch' } + useRule { name 'availability zone is related to a complex' } + useRule { + name 'availability-zone must be related to a service-capability and service-capability.service-type matches naming convention' + attributes 'relationship-list.relationship[*]' + } + } +} + +rule { + name 'availability-zone name matches naming convention' + category 'INVALID_NAME' + description 'Naming convention must match xxxxx-esx-aznn' + errorText 'Invalid name - attribute must match xxxxx-esx-aznn (where x = alphanumeric and n = numeric)' + severity 'MINOR' + attributes 'name' + validate 'name != null && name.matches("[a-z0-9]{5}-esx-az[0-9]{2}")' +} + +rule { + name 'hypervisor-type matches naming convention' + category 'INVALID_NAME' + description 'Naming convention must match the string esx' + errorText 'Invalid name - attribute must match the string esx' + severity 'CRITICAL' + attributes 'name' + validate 'name != null && name.matches("esx")' +} + +rule { + name 'operational-state must be operationalState' + category 'INVALID_VALUE' + description 'The value of operational-state must be operationalState' + errorText 'Invalid value - attribute must be set to operationalState' + severity 'CRITICAL' + attributes 'opvalue' + validate 'opvalue != null && opvalue.matches("operationalState")' +} + +rule { + name 'availability zone is related to dvs-switch' + category 'MISSING_REL' + description 'Validates that an availability zone is related to a dvs-switch' + errorText 'Missing relationship - availability zone is not related to a dvs-switch' + severity 'MAJOR' + attributes 'relationship-list.relationship[*].related-to' + validate 'related-to != null && related-to.contains("dvs-switch")' +} + +rule { + name 'availability zone is related to a complex' + category 'MISSING_REL' + description 'Validates that an availability zone is related to a complex' + errorText 'Missing relationship - availability zone is not related to a complex' + severity 'CRITICAL' + attributes 'relationship-list.relationship[*].related-to' + validate 'related-to != null && related-to.contains("complex")' +} + +rule { + name 'availability-zone must be related to a service-capability and service-capability.service-type matches naming convention' + category 'INVALID_NAME' + description 'Validates that an availability-zone is related to a service-capability and service-capability.service-type matches naming convention' + errorText 'Invalid name - availability-zone must be related to a service-capability and service-capability.service-type must be set to SDN-ETHERNET-INTERNET' + severity 'CRITICAL' + attributes 'relationships' + validate ''' + def getStringProperty = { jsonObject, propertyName -> jsonObject.get(propertyName)?.getAsString() } + + if (!relationships.find { getStringProperty(it, "related-to") == "service-capability" }) { return true } + + return relationships.findAll { getStringProperty(it, "related-to") == "service-capability" } + .findAll { it."related-to-property" != null } + .collect { it."relationship-data".get(0) } + .findAll { getStringProperty(it, "relationship-key") == "service-capability.service-type" } + .find { getStringProperty(it, "relationship-value") == "SDN-ETHERNET-INTERNET" } + ''' +} diff --git a/bundleconfig/etc/rules/aai-event/entity-complex.groovy b/bundleconfig/etc/rules/aai-event/entity-complex.groovy new file mode 100644 index 0000000..48d2f26 --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-complex.groovy @@ -0,0 +1,146 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'complex' + validation { + useRule { + name 'CLLI' + attributes 'physical-location-id' + } + useRule { + name 'not AAI default' + attributes 'street1' + } + useRule { + name 'not AAI default' + attributes 'city' + } + useRule { + name 'not AAI default' + attributes 'state' + } + useRule { + name 'not AAI default' + attributes 'postal-code' + } + useRule { + name 'not AAI default' + attributes 'region' + } + useRule { + name 'not AAI default' + attributes 'country' + } + useRule { + name 'critical not AAI default' + attributes 'physical-location-type' + } + useRule { + name 'length five or null' + attributes 'complex-name' + } + useRule {name 'complex is related to availability zone' } + useRule {name 'complex is related to 1 oam-network' } + useRule { + name 'if a customer is related to an oam-network then oam-network.network-name must match naming convention' + attributes 'relationship-list.relationship[*]' + } + } +} + +rule { + name 'CLLI' + category 'FIELD_LENGTH' + description 'Field must be 8 or 11 characters long' + errorText 'Invalid length - field must be 8 or 11 characters long' + severity 'CRITICAL' + attributes 'field' + validate 'field.size() == 8 || field.size() == 11' +} + +rule { + name 'not AAI default' + category 'FIELD_LENGTH' + description 'Invalid length - field must not be AAIDEFAULT or null' + errorText 'Invalid Value - must not be AAIDEFAULT or null' + severity 'MINOR' + attributes 'field' + validate 'field != null && field.size() > 0 && !field.equalsIgnoreCase("AAIDEFAULT")' +} + +rule { + name 'length five or null' + category 'FIELD_LENGTH' + description 'Field must be 5 characters long or null' + errorText 'Invalid Length - field must be 5 characters long or null' + severity 'MINOR' + attributes 'field' + validate 'field == null || field.size() == 5' +} + +rule { + name 'critical not AAI default' + category 'INVALID_VALUE' + description 'Field must not be AAIDEFAULT or null' + errorText 'Invalid Value - must not be AAIDEFAULT or null' + severity 'CRITICAL' + attributes 'field' + validate 'field != null && field.size() > 0 && !field.equalsIgnoreCase("AAIDEFAULT")' +} + +rule { + name 'complex is related to availability zone' + category 'MISSING_REL' + description 'Validates that a complex is related to an availability zone' + errorText 'Missing relationship - a complex must be related to an availability zone' + severity 'CRITICAL' + attributes 'relationship-list.relationship[*].related-to' + validate 'related-to != null && related-to.contains("availability-zone")' +} + +rule { + name 'complex is related to 1 oam-network' + category 'MISSING_REL' + description 'Validates that a complex is related to 1 oam-network (and not more than 1 oam-network)' + errorText 'Missing relationship - complex must be related to 1 oam-network' + severity 'MAJOR' + attributes 'relationship-list.relationship[*].related-to' + validate 'related-to != null && related-to.count("oam-network") == 1' +} + +rule { + name 'if a customer is related to an oam-network then oam-network.network-name must match naming convention' + category 'INVALID_NAME' + description 'validates that if a customer is related to an oam-network then oam-network.network-name must match naming convention' + errorText 'Invalid name - if a customer is related to an oam-network then network-name must start with VLAN' + severity 'MINOR' + attributes 'relationships' + validate ''' + def getStringProperty = { jsonObject, propertyName -> jsonObject.get(propertyName).getAsString() } + + relatedToOamNetwork = relationships.findAll { getStringProperty(it, "related-to") == "oam-network" } + + networkNameIsValid = relationships.findAll { getStringProperty(it, "related-to") == "oam-network" } + .collect { it."related-to-property".get(0) } + .findAll { getStringProperty(it, "property-key") == "oam-network.network-name" } + .find { getStringProperty(it, "property-value").startsWith("VLAN") } + + return !relatedToOamNetwork || networkNameIsValid + ''' +} diff --git a/bundleconfig/etc/rules/aai-event/entity-generic-vnf.groovy b/bundleconfig/etc/rules/aai-event/entity-generic-vnf.groovy new file mode 100644 index 0000000..d813eea --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-generic-vnf.groovy @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'generic-vnf' + validation { + useRule { + name 'prov-status' + attributes 'prov-status' + } + useRule { + name 'valid_ipv4_addr' + attributes 'ipv4-oam-address' + } + useRule { + name 'ipv4_addr_present' + attributes 'equipment-role', 'l-interfaces.l-interface[*].l3-interface-ipv4-address-list' + } + } +} + +rule { + name 'valid_ipv4_addr' + category 'INVALID_VALUE' + description 'Validate an IPv4 address' + errorText 'Invalid value - attribute is not a valid IPv4 address' + severity 'MINOR' + attributes 'ipaddr' + validate 'ipaddr != null && ipaddr.matches("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])")' +} + +// If generic-vnf.equipment-role="UCPE" and there is an l-interface - then there must be an IPV4 address related to the l-interface +rule { + name 'ipv4_addr_present' + category 'MISSING_REL' + description 'Validates that ICPE equipment has a related IPv4 address' + errorText 'UCPE l-interface missing the IPv4 relationship' + severity 'MINOR' + attributes 'equipment', 'ipv4' + validate 'equipment != "UCPE" || ipv4 != null' +} diff --git a/bundleconfig/etc/rules/aai-event/entity-newvce.groovy b/bundleconfig/etc/rules/aai-event/entity-newvce.groovy new file mode 100644 index 0000000..dce812a --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-newvce.groovy @@ -0,0 +1,43 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'newvce' + validation { + useRule { + name 'prov-status' + attributes 'prov-status' + } + useRule { + name 'vnf-name' + attributes 'vnf-name' + } + useRule { + name 'vnf-type' + attributes 'vnf-type' + } + useRule { + name 'valid_ipv4_addr' + attributes 'ipv4-oam-address' + } + useRule { + name 'heat-stack-id equals first 11 bytes of vnf-name' + attributes 'heat-stack-id', 'vnf-name' + } + } +} diff --git a/bundleconfig/etc/rules/aai-event/entity-oam-network.groovy b/bundleconfig/etc/rules/aai-event/entity-oam-network.groovy new file mode 100644 index 0000000..a2e634a --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-oam-network.groovy @@ -0,0 +1,81 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'oam-network' + validation { + useRule { + name 'network-name value' + attributes 'network-name' + } + useRule { + name 'cvlan-tag equals last four digits of network-name' + attributes 'cvlan-tag', 'network-name' + } + useRule { + name 'valid_ipv4_oam_gw_addr' + attributes 'ipv4-oam-gateway-address' + } + useRule { + name 'ipv4_oam_gw_addr_prefix_length' + attributes 'ipv4-oam-gateway-address-prefix-length' + } + } +} + +rule { + name 'network-name value' + category 'INVALID_VALUE' + description 'The value of network-name must be VLAN-OAM-1323 or VLAN-OAM-1321' + errorText 'Invalid value - the value of network-name must be VLAN-OAM-1323 or VLAN-OAM-1321' + severity 'MINOR' + attributes 'name' + validate 'name != null && name.matches("VLAN-OAM-1323|VLAN-OAM-1321")' +} + +rule { + name 'cvlan-tag equals last four digits of network-name' + category 'INVALID_VALUE' + description 'The value of cvlan-tag must match the last 4 digits of network-name' + errorText 'Invalid value - the value of cvlan-tag must match the last 4 digits of network-name' + severity 'MINOR' + attributes 'cvlantag', 'networkname' + validate '''def lastFour = { str -> str ? str.drop(str.size() - 4) : null } + cvlantagStr=String.valueOf(cvlantag) + cvlantagStr.equals(lastFour(networkname))''' +} + +rule { + name 'valid_ipv4_oam_gw_addr' + category 'INVALID_VALUE' + description 'Validate an IPv4 address' + errorText 'Invalid value - attribute is not a valid IPv4 address' + severity 'MAJOR' + attributes 'ipaddr' + validate 'ipaddr != null && ipaddr.matches("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])")' +} + +rule { + name 'ipv4_oam_gw_addr_prefix_length' + category 'INVALID_VALUE' + description 'Invalid value - field value must be 26' + errorText 'Invalid Value - field value must be 26' + severity 'MAJOR' + attributes 'field' + validate 'field != null && field == 26' +} diff --git a/bundleconfig/etc/rules/aai-event/entity-port-group.groovy b/bundleconfig/etc/rules/aai-event/entity-port-group.groovy new file mode 100644 index 0000000..8fdf2ce --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-port-group.groovy @@ -0,0 +1,45 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'port-group' + validation { + useRule { + name 'heat-stack-id' + } + } +} + +/* + * This rule validates the heat-stack-id attribute value based on the corresponding orchestration-status attribute value. + * If the orchestration-status is "created", then the heat-stack-id cannot be null or empty, or equal to "heat123". + * If the orchestration-status is "pending create", then the heat-stack-id must be null or empty, or equal to "heat123". + */ +rule { + name 'heat-stack-id' + category 'DEPENDENCY_ERR' + description 'Validates that the heat-stack-id value is valid for various Orchestration Status values' + errorText 'The heat-stack-id value is invalid for the current orchestration-status.' + severity 'CRITICAL' + attributes 'orchestration-status', 'heat-stack-id' + validate '''switch (orchestration-status?.toLowerCase()) { + case "created": return !(heat-stack-id in [null, "", "heat123"]) + case "pending create": return heat-stack-id in [null, "", "heat123"] + default: orchestration-status != null // true + }''' +} diff --git a/bundleconfig/etc/rules/aai-event/entity-pserver.groovy b/bundleconfig/etc/rules/aai-event/entity-pserver.groovy new file mode 100644 index 0000000..6d00b42 --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-pserver.groovy @@ -0,0 +1,92 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'pserver' + validation { + useRule { + name 'equip-type' + attributes 'equip-type' + } + useRule { + name 'pserver.name' + attributes 'hostname' + } + useRule { + name 'pserver.name' + attributes 'ptnii-equip-name' + } + useRule {name 'pserver is related to 1 complex' } + useRule { + name 'pserver inv-status attribute allowed values' + attributes 'inv-status' + } + } +} + +rule { + name 'equip-type' + category 'INVALID_VALUE' + description 'Invalid value - equip-type must not be toa or hitachi - an empty value is ok' + errorText 'Invalid value - attribute must not have a value of toa or hitachi' + severity 'MINOR' + validate ''' equip-type == null || + (!equip-type.equalsIgnoreCase("toa") && + !equip-type.equalsIgnoreCase("hitachi")) + ''' +} + +rule { + name 'pserver.name' + category 'INVALID_VALUE' + description 'Invalid value - field must not contain .infra.aic.att.net' + errorText 'Invalid value - field must not contain .infra.aic.att.net' + severity 'MINOR' + attributes 'name' + validate 'name == null || !name.matches(".*[.]infra[.]aic[.]att[.]net.*")' +} + +rule { + name 'pserver is related to 1 complex' + category 'MISSING_REL' + description 'Validates that a pserver is related to 1 complex' + errorText 'Missing relationship - pserver must be related to 1 complex' + severity 'MINOR' + attributes 'relationship-list.relationship[*].related-to' + validate 'related-to != null && related-to.count("complex") == 1' +} + +rule { + name 'pserver inv-status attribute allowed values' + category 'INVALID_VALUE' + description 'inv-status value restricted to one of Deployed, In Service, Not Specified, Pending Delete, Planned, Planned Modify' + errorText 'Invalid inv-status value. Must be Deployed, In Service, Not Specified, Pending Delete, Planned, Planned Modify' + severity 'CRITICAL' + attributes 'status' + validate '''switch (status) { + case null: + case "Deployed": + case "In Service": + case "Not Specified": + case "Pending Delete": + case "Planned": + case "Planned Modify": + return true + default: return false + }''' +} diff --git a/bundleconfig/etc/rules/aai-event/entity-vce.groovy b/bundleconfig/etc/rules/aai-event/entity-vce.groovy new file mode 100644 index 0000000..bc985b8 --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-vce.groovy @@ -0,0 +1,94 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'vce' + validation { + useRule { + name 'prov-status' + attributes 'prov-status' + } + useRule { + name 'uppercase_alpha' + attributes 'vnf-name2' + } + useRule { + name 'vnf-name' + attributes 'vnf-name' + } + useRule { + name 'vnf-type' + attributes 'vnf-type' + } + useRule { + name 'vce.vpe-id' + attributes 'vpe-id' + } + useRule { + name 'valid_ipv4_addr' + attributes 'ipv4-oam-address' + } + useRule { name 'heat-stack-id' } + useRule { name 'vce is related to vserver and service and complex' } + useRule { name 'vce is related to an availability zone' } + useRule { + name 'heat-stack-id equals first 11 bytes of vnf-name' + attributes 'heat-stack-id', 'vnf-name' + } + } +} + +rule { + name 'uppercase_alpha' + category 'INVALID_NAME' + description 'naming convention is UPPERCASE (alphanumeric)' + errorText 'Invalid name - the attribute must be UPPERCASE (alphanumeric)' + severity 'MINOR' + attributes 'name' + validate 'name != null && name.matches("[A-Z,0-9, ]+")' +} + +rule { + name 'vce.vpe-id' + category 'INVALID_NAME' + description 'Naming convention must start with VPESAT and end with lowercase 401me6' + errorText 'Invalid name - attribute must start with VPESAT and end with lowercase 401me6' + severity 'MINOR' + attributes 'name' + validate 'name != null && name.matches("^VPESAT\\\\.*401me6")' +} + +rule { + name 'vce is related to vserver and service and complex' + category 'MISSING_REL' + description 'Validates that a vce is related to a vserver and service-instance and complex' + errorText 'Missing relationship - vce is not related to a vserver and service-instance and complex' + severity 'MAJOR' + attributes 'relationship-list.relationship[*].related-to' + validate 'related-to != null && related-to.contains("vserver") && related-to.contains("service-instance") && related-to.contains("complex")' +} + +rule { + name 'vce is related to an availability zone' + category 'MISSING_REL' + description 'Validates that a vce is related to an availability zone' + errorText 'Missing relationship - vce is not related to an availability zone' + severity 'MAJOR' + attributes 'relationship-list.relationship[*].related-to' + validate 'related-to != null && related-to.contains("availability-zone")' +} diff --git a/bundleconfig/etc/rules/aai-event/entity-vnfc.groovy b/bundleconfig/etc/rules/aai-event/entity-vnfc.groovy new file mode 100644 index 0000000..9a4300f --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-vnfc.groovy @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'vnfc' + validation { + useRule { + name 'prov-status' + attributes 'prov-status' + } + } +} diff --git a/bundleconfig/etc/rules/aai-event/entity-vpls-pe.groovy b/bundleconfig/etc/rules/aai-event/entity-vpls-pe.groovy new file mode 100644 index 0000000..30d8c92 --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-vpls-pe.groovy @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'vpls-pe' + validation { + useRule { + name 'prov-status' + attributes 'prov-status' + } + } +} diff --git a/bundleconfig/etc/rules/aai-event/entity-vserver.groovy b/bundleconfig/etc/rules/aai-event/entity-vserver.groovy new file mode 100644 index 0000000..f6b3471 --- /dev/null +++ b/bundleconfig/etc/rules/aai-event/entity-vserver.groovy @@ -0,0 +1,151 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'vserver' + validation { + useRule {name 'vserver is related to 0 or 1 image' } + useRule {name 'vserver is related to 0 or 1 flavor' } + useRule {name 'vserver is related to 1 pserver' } + useRule {name 'vserver is related to vpe and vserver-name matches naming convention' } + useRule {name 'vserver is related to vce and vserver-name matches naming convention' } + useRule { + name 'vserver related to TRINITY image and generic-vnf.vnf-name matches naming convention' + attributes 'relationship-list.relationship[*]' + } + useRule { + name 'vserver is related to a TRINITY image and vserver-name matches naming convention' + attributes 'relationship-list.relationship[*]', 'vserver-name' + } + useRule { + name 'vserver is related to a vnf (vce or newvce or vpe or generic-vnf)' + attributes 'relationship-list.relationship[*].related-to' + } + } +} + +rule { + name 'vserver related to TRINITY image and generic-vnf.vnf-name matches naming convention' + category 'INVALID_NAME' + description 'Validates that if vserver is related to an image named TRINITY, then the related generic-vnf name matches naming convention' + errorText 'Invalid name - if vserver is related to an image named TRINITY, then the related generic-vnf name must match xxxxnnnnv (where x = character and n = number)' + severity 'MINOR' + attributes 'relationships' + validate ''' + def getStringProperty = { jsonObject, propertyName -> jsonObject.get(propertyName)?.getAsString() } + + vnf_name = relationships.findAll { getStringProperty(it, "related-to") == "generic-vnf" } + .findAll { it."related-to-property" != null } + .collect { it."related-to-property".get(0) } + .find { getStringProperty(it, "property-key") == "generic-vnf.vnf-name" } + .findResult { getStringProperty(it, "property-value") } + + relatedToTrinity = relationships.findAll { getStringProperty(it, "related-to") == "image" } + .findAll { it."related-to-property" != null } + .collect { it."related-to-property".get(0) } + .findAll { getStringProperty(it, "property-key") == "image.image-name" } + .find { getStringProperty(it, "property-value")?.startsWith("TRINITY") } + + // If (and only if) related to TRINITY then check the generic-vnf name + return !relatedToTrinity || vnf_name?.matches("[a-z]{4}[0-9]{4}v") + ''' +} + +rule { + name 'vserver is related to a vnf (vce or newvce or vpe or generic-vnf)' + category 'MISSING_REL' + description 'Validates that a vserver is related to a vnf (vce or newvce or vpe or generic-vnf)' + errorText 'Missing relationship - a vserver must be related to a vnf (vce or newvce or vpe or generic-vnf)' + severity 'MINOR' + attributes 'related-to' + validate 'related-to != null && (related-to.contains("vce") || related-to.contains("newvce") || related-to.contains("vpe") || related-to.contains("generic-vnf"))' +} + +rule { + name 'vserver is related to 1 pserver' + category 'MISSING_REL' + description 'Validates that a vserver is related to 1 pserver (and not more than 1 pserver)' + errorText 'Missing relationship - vserver must be related to 1 pserver' + severity 'MINOR' + attributes 'relationship-list.relationship[*].related-to' + validate 'related-to != null && related-to.count("pserver") == 1' +} + +rule { + name 'vserver is related to 0 or 1 image' + category 'MISSING_REL' + description 'Validates that a vserver is either not related to an image or related to only 1 image' + errorText 'Missing relationship - vserver must be related to 0 or 1 image' + severity 'MINOR' + attributes 'relationship-list.relationship[*].related-to' + validate 'related-to == null || related-to.count("image") <= 1' +} + +rule { + name 'vserver is related to 0 or 1 flavor' + category 'MISSING_REL' + description 'Validates that a vserver is either not related to a flavor or related to only 1 flavor' + errorText 'Missing relationship - vserver must be related to 0 or 1 flavor' + severity 'MINOR' + attributes 'relationship-list.relationship[*].related-to' + validate 'related-to == null || related-to.count("flavor") <= 1' +} + +rule { + name 'vserver is related to vpe and vserver-name matches naming convention' + category 'INVALID_NAME' + description 'Validates that if a vserver is related to a vpe then vserver-name must contain me6' + errorText 'Invalid name - if vserver is related to vpe then vserver-name must contain me6' + severity 'MINOR' + attributes 'relationship-list.relationship[*].related-to', 'vserver-name' + validate '!related-to.contains("vpe") || vserver-name =~ "me6"' +} + +rule { + name 'vserver is related to vce and vserver-name matches naming convention' + category 'INVALID_NAME' + description 'Validates that if a vserver is related to a vce then vserver-name must match naming convention' + errorText 'Invalid name - if vserver is related to vce then vserver-name must match xxxxxxxxvbcnnceb (where x = alphanumeric and n = numeric)' + severity 'MINOR' + attributes 'relationship-list.relationship[*].related-to', 'vserver-name' + validate '!related-to.contains("vce") || vserver-name =~ "[a-z0-9]{8}vbc[0-9]{2}ceb"' +} + + + +rule { + name 'vserver is related to a TRINITY image and vserver-name matches naming convention' + category 'INVALID_NAME' + description 'Validates that if vserver is related to an image named TRINITY, then the vserver name matches naming convention' + errorText 'Invalid name - if vserver is related to an image named TRINITY, then the vserver name must match xxxxnnnnvmnnn (where x = character and n = number)' + severity 'MINOR' + attributes 'relationships', 'vservername' + validate ''' + def getStringProperty = { jsonObject, propertyName -> jsonObject.get(propertyName)?.getAsString() } + + relatedToTrinity = relationships.findAll { getStringProperty(it, "related-to") == "image" } + .findAll { it."related-to-property" != null } + .collect { it."related-to-property".get(0) } + .findAll { getStringProperty(it, "property-key") == "image.image-name" } + .find { getStringProperty(it, "property-value").startsWith("TRINITY") } + + // If (and only if) related to TRINITY then check the vserver name + return !relatedToTrinity || vservername != null && vservername ==~ "[a-z]{4}[0-9]{4}vm[0-9]{3}" + ''' +} + diff --git a/bundleconfig/etc/rules/gizmo-event/common_rules.groovy b/bundleconfig/etc/rules/gizmo-event/common_rules.groovy new file mode 100644 index 0000000..b30816e --- /dev/null +++ b/bundleconfig/etc/rules/gizmo-event/common_rules.groovy @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +rule { + name 'valid_ipv4_addr' + category 'INVALID_VALUE' + description 'Validate an IPv4 address' + errorText 'Invalid value - attribute is not a valid IPv4 address' + severity 'MINOR' + attributes 'ipaddr' + validate 'ipaddr != null && ipaddr.matches("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])")' +} diff --git a/bundleconfig/etc/rules/gizmo-event/pserver-rules.groovy b/bundleconfig/etc/rules/gizmo-event/pserver-rules.groovy new file mode 100644 index 0000000..79b3cc2 --- /dev/null +++ b/bundleconfig/etc/rules/gizmo-event/pserver-rules.groovy @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'pserver' + validation { + useRule { + name 'valid_ipv4_addr' + attributes 'vertex.properties.ipv4-oam-address' + } + } +} diff --git a/bundleconfig/etc/rules/poa-event/default-rules.groovy b/bundleconfig/etc/rules/poa-event/default-rules.groovy new file mode 100644 index 0000000..8397abd --- /dev/null +++ b/bundleconfig/etc/rules/poa-event/default-rules.groovy @@ -0,0 +1,168 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + name 'POA-EVENT' + indexing { + indices 'default-rules' + } + validation { + useRule { + name 'Verify AAI nf-naming-code' + attributes 'context-list.aai.vf-list[*]' + } + useRule { + name 'port-mirroring-AAI-has-valid-vnfc' + attributes 'context-list.sdc.vf-list[*]', 'context-list.aai.vf-list[*]' + } + useRule { + name 'port-mirroring-SDC-vnfc-types-missing' + attributes 'context-list.sdc.vf-list[*]', 'context-list.aai.vf-list[*]' + } + useRule { + name 'port-mirroring-AAI-vnfc-type-exists-in-SDC-SUCCESS' + attributes 'context-list.sdc.vf-list[*]', 'context-list.aai.vf-list[*]' + } + } +} + +rule { + name 'Verify AAI nf-naming-code' + category 'INVALID_VALUE' + description 'Validate that nf-naming-code exists and is populated in AAI VNF instance' + errorText 'The nf-naming-code is not populated in AAI VNF instance' + severity 'CRITICAL' + attributes 'vfList' + validate ''' + def parsed = new groovy.json.JsonSlurper().parseText(vfList.toString()) + for (vf in parsed) { + String nfNamingCode = vf."nf-naming-code" + if (nfNamingCode == null || nfNamingCode.equals("")) { + return false + } + } + return true + ''' +} + +rule { + name 'port-mirroring-AAI-has-valid-vnfc' + category 'INVALID_VALUE' + description 'Validate that each VNFC instance in AAI conforms to a VNFC type defined in SDC model' + errorText 'AAI VNFC instance includes non-specified type in design SDC model' + severity 'ERROR' + attributes 'sdcVfList', 'aaiVfList' + validate ''' + def slurper = new groovy.json.JsonSlurper() + def parsedSdc = slurper.parseText(sdcVfList.toString()) + def parsedAai = slurper.parseText(aaiVfList.toString()) + + // gather all SDC nfc-naming-codes + List sdcNfcNamingCodeList = new ArrayList<>() + parsedSdc.each { + for(sdcVnfc in it.vnfc) { + String sdcNfcNamingCode = sdcVnfc."nfc-naming-code" + if(sdcNfcNamingCode != null) { + sdcNfcNamingCodeList.add(sdcNfcNamingCode) + } + } + } + + // check that all SDC nfc-naming-codes exist in AAI + parsedAai.each { + for(aaiVnfc in it.vnfc) { + String aaiNfcNamingCode = aaiVnfc."nfc-naming-code" + if(aaiNfcNamingCode != null) { + if(!sdcNfcNamingCodeList.contains(aaiNfcNamingCode)) { + return false + } + } + } + } + return true + ''' +} + + +rule { + name 'port-mirroring-SDC-vnfc-types-missing' + category 'INVALID_VALUE' + description 'Validate that each VNFC type specified in SDC model exists in AAI' + errorText 'Design has specified types but not all of them exist in AAI' + severity 'WARNING' + attributes 'sdcVfList', 'aaiVfList' + validate ''' + def getNfcNamingCodeSet = { parsedEntity -> + Set namingCodeSet = new HashSet<>() + parsedEntity.each { + for(vnfcItem in it."vnfc") { + println "vnfc: " + vnfcItem + String namingCode = vnfcItem."nfc-naming-code" + if(namingCode != null) { + namingCodeSet.add(namingCode) + } + } + } + return namingCodeSet + } + + // gather all unique nfc-naming-codes from AAI and SDC + def slurper = new groovy.json.JsonSlurper() + def aaiNfcNamingCodeSet = getNfcNamingCodeSet(slurper.parseText(aaiVfList.toString())) as java.util.HashSet + def sdcNfcNamingCodeSet = getNfcNamingCodeSet(slurper.parseText(sdcVfList.toString())) as java.util.HashSet + + println "AAI: " + aaiNfcNamingCodeSet + println "SDC: " + sdcNfcNamingCodeSet + + // check that all nfc-naming-codes in SDC exist in AAI + return aaiNfcNamingCodeSet.containsAll(sdcNfcNamingCodeSet) + ''' +} + + +rule { + name 'port-mirroring-AAI-vnfc-type-exists-in-SDC-SUCCESS' + category 'SUCCESS' + description 'Verify that every vnfc in sdc has been created in AAI' + errorText 'Every vnfc type specified in sdc has been created in AAI' + severity 'INFO' + attributes 'sdcVfList', 'aaiVfList' + validate ''' + def getNfcNamingCodeSet = { parsedEntity -> + Set namingCodeSet = new HashSet<>() + parsedEntity.each { + for(vnfcItem in it."vnfc") { + String namingCode = vnfcItem."nfc-naming-code" + if(namingCode != null) { + namingCodeSet.add(namingCode) + } + } + } + return namingCodeSet + } + + // gather all unique nfc-naming-codes from AAI and SDC + def slurper = new groovy.json.JsonSlurper() + def aaiNfcNamingCodeSet = getNfcNamingCodeSet(slurper.parseText(aaiVfList.toString())) as java.util.HashSet + def sdcNfcNamingCodeSet = getNfcNamingCodeSet(slurper.parseText(sdcVfList.toString())) as java.util.HashSet + + // check that all nfc-naming-codes in SDC exist in AAI + // return false if all SDC naming codes exist in AAI to trigger an INFO violation + return !aaiNfcNamingCodeSet.containsAll(sdcNfcNamingCodeSet) + ''' +} diff --git a/bundleconfig/etc/rules/spike-event/common_rules.groovy b/bundleconfig/etc/rules/spike-event/common_rules.groovy new file mode 100644 index 0000000..b30816e --- /dev/null +++ b/bundleconfig/etc/rules/spike-event/common_rules.groovy @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +rule { + name 'valid_ipv4_addr' + category 'INVALID_VALUE' + description 'Validate an IPv4 address' + errorText 'Invalid value - attribute is not a valid IPv4 address' + severity 'MINOR' + attributes 'ipaddr' + validate 'ipaddr != null && ipaddr.matches("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])")' +} diff --git a/bundleconfig/etc/rules/spike-event/pserver-rules.groovy b/bundleconfig/etc/rules/spike-event/pserver-rules.groovy new file mode 100644 index 0000000..79b3cc2 --- /dev/null +++ b/bundleconfig/etc/rules/spike-event/pserver-rules.groovy @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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===================================================== + */ + +entity { + type 'pserver' + validation { + useRule { + name 'valid_ipv4_addr' + attributes 'vertex.properties.ipv4-oam-address' + } + } +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..f6eb7d7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,505 @@ + + + + 4.0.0 + + com.ecomp.aai + validation-service + 1.2.4-SNAPSHOT + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + 1.5.13.RELEASE + org.onap.aai.validation.ValidationServiceApplication + 9500 + 9501 + 1.2.2 + 1.2.1 + 1.0.0 + 1.2.2 + 1.0 + 2.7 + 2.2.0 + 1.10 + 1.1.6 + 4.5.2 + 2.4.3-01 + 2.9.2-01 + 2.6.2 + 1.3 + 20160212 + 1.2.4 + 0.7.9 + 2.23 + 1.2.4 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework + spring-webmvc + + + org.codehaus.groovy + groovy-all + + + javax.ws.rs + javax.ws.rs-api + 2.0.1 + + + commons-io + commons-io + 2.4 + + + org.apache.commons + commons-lang3 + 3.7 + + + commons-collections + commons-collections + + + dom4j + dom4j + + + org.eclipse.jetty + jetty-security + + + + + + ch.qos.logback + logback-classic + + + + org.onap.aai.logging-service + logging-api + ${version.org.onap.aai.logging-service} + + + + org.onap.aai.logging-service + common-logging + ${version.org.onap.aai.logging-service} + + + + org.onap.aai.logging-service + eelf-logging + ${version.org.onap.aai.logging-service} + + + + com.att.eelf + eelf-core + 1.0.1-oss + + + + + + org.onap.aai + rest-client + ${version.org.onap.aai-rest-client} + + + + + + org.onap.aai.event-client + event-client-dmaap + ${version.org.onap.aai.event.client} + + + + com.google.code.gson + gson + + + + com.jayway.jsonpath + json-path + + + + commons-configuration + commons-configuration + ${version.commons-configuration} + + + + jaxen + jaxen + + + + org.apache.httpcomponents + httpclient + + + + org.eclipse.persistence + org.eclipse.persistence.moxy + ${version.org.eclipse.persistence.moxy} + + + + org.json + json + ${version.org.json.json} + + + + org.glassfish.jersey.core + jersey-client + + + + org.onap.aai.aai-common + aai-schema-ingest + ${version.aai.aai-schema-ingest} + + + junit + junit + test + + + + org.mockito + mockito-all + 1.10.19 + test + + + + org.hamcrest + hamcrest-library + test + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + true + + + + + repackage + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + groovy-eclipse-compiler + true + 1.8 + 1.8 + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${version.org.codehaus.groovy.groovy-eclipse-compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${version.org.codehaus.groovy.groovy-eclipse-batch} + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack + prepare-package + + unpack + + + + + org.onap.aai.aai-common + aai-schema + ${version.org.openecomp.aai.aai-schema} + jar + oxm/ + ${project.build.directory}/bundleconfig/etc/ + + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + generate-resources + + com.tenxerconsulting.swagger.doclet.ServiceDoclet + + com.tenxerconsulting + swagger-doclet + 1.1.3 + + apidocs + ${project.build.directory}/../staticContent + false + -apiVersion 1 -docBasePath + http://localhost:${serverPort}/services/validation-service/v1/static + -apiBasePath + http://localhost:${serverPort} + + + jar + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + + add-integration-test-sources + generate-test-sources + + add-test-source + + + + + src/integration-test/java + + + + + + add-integration-test-resources + generate-test-resources + + add-test-resource + + + + + + + true + src/integration-test/resources + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + + ${skip.unit.tests} + + + **/IT*.java + + + . + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.18 + + + + integration-tests + + integration-test + + + + ${skip.integration.tests} + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.2 + + + copy-docker-file + package + + copy-resources + + + ${project.build.directory} + true + + + ${basedir}/src/main/docker + true + + **/* + + + + ${basedir}/src/main/bin/ + + + + + + copy-bundleconfig + package + + copy-resources + + + ${project.build.directory}/bundleconfig + false + + + ${basedir}/bundleconfig/ + true + + etc/appprops/ + etc/rules/ + + + + + + + + + + org.jacoco + jacoco-maven-plugin + ${version.jacoco.maven.plugin} + + + prepare-agent + + prepare-agent + + + + report + package + + report + + + + + + + + + + dev + + true + + + dev + + true + false + + + + + integration-test + + integration-test + + false + true + + + + + diff --git a/project-configs/code-tools/sonar-secret.txt b/project-configs/code-tools/sonar-secret.txt new file mode 100644 index 0000000..9036e07 --- /dev/null +++ b/project-configs/code-tools/sonar-secret.txt @@ -0,0 +1 @@ +7TP5jKdtMb+0EtW4Trbbnw== \ No newline at end of file diff --git a/project-configs/maven/conf/settings.xml b/project-configs/maven/conf/settings.xml new file mode 100644 index 0000000..999749e --- /dev/null +++ b/project-configs/maven/conf/settings.xml @@ -0,0 +1,193 @@ + + + + + nexus + + *,!rim2e,!maven-restlet,!alfresco-proxy,!ssf,!maven-releases,!maven-hazelcast,!essdsdp-3rd-party,!cadi,!cadi-gso,!m2eProcessor,!csi,!ecomp_aai,!osd-3rd-party,!eci-3rd-party,!2020SAPC + http://mavencentral.it.att.com:8084/nexus/content/groups/swm + + + + nexusrestlet + maven-restlet + http://mavencentral.it.att.com:8084/nexus/content/repositories/restlet-releases + + + + nexus + * + http://mavencentral.it.att.com:8084/nexus/content/groups/ecomp_aai + + + + + nexus + + + + + central + http://central + + true + + never + + + true + always + + + + + + + central + http://central + + true + + + true + + + + + + nexus-csi + + + + + csi + http://mavencentral.it.att.com:8084/nexus/content/groups/csi + + true + + never + + + true + always + + + + + ecomp_aai + http://mavencentral.it.att.com:8084/nexus/content/groups/ecomp_aai + + true + never + + + true + always + + + + 2020SAPC + http://mavencentral.it.att.com:8084/nexus/content/groups/2020SAPC + + true + never + + + true + always + + + + + + csi + http://mavencentral.it.att.com:8084/nexus/content/groups/csi + + true + + + true + + + + + + nexus-ecomp_aai + + + ecomp_aai + http://mavencentral.it.att.com:8084/nexus/content/groups/ecomp_aai + + true + never + + + true + always + + + + + + sonar + + true + + + + http://10.147.107.156:9000 + jdbc:h2:tcp://10.223.41.156:9092/sonar + + + + + + nexus + nexus-csi + nexus-ecomp_aai + + + + org.sonatype.plugins + + + + nexus + m92680 + t3b8r8j4s8 + + + ecomp_aai + m92680 + t3b8r8j4s8 + + + swm + m97870 + + + \ No newline at end of file diff --git a/src/integration-test/java/org/onap/aai/validation/itest/ITestModelCacheManager.java b/src/integration-test/java/org/onap/aai/validation/itest/ITestModelCacheManager.java new file mode 100644 index 0000000..8584a2b --- /dev/null +++ b/src/integration-test/java/org/onap/aai/validation/itest/ITestModelCacheManager.java @@ -0,0 +1,121 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.itest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.io.File; +import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import org.dom4j.Element; +import org.dom4j.tree.DefaultElement; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.aai.validation.config.ModelConfig; +import org.onap.aai.validation.config.RestConfig; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.modeldriven.ModelCacheManager; +import org.onap.aai.validation.modeldriven.ModelId; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"classpath:model-cache-manager/itest-validation-service-beans.xml"}) +public class ITestModelCacheManager { + + static { + System.setProperty("AJSC_HOME", "."); + System.setProperty("CONFIG_HOME", System.getProperty("user.dir") + File.separator); + } + + private static final String MODEL_ID_ATTRIBUTE = "model-invariant-id"; + private static final String CONNECTOR_MODEL_ID = "connector-widget-id"; + + @Inject + private RestConfig restConfig; + + @Inject + private RestConfig fileBasedRestConfig; + + @Inject + private ModelConfig modelConfig; + + @Test + public void testReadModelFromRestClient() throws ValidationServiceException { + ModelCacheManager modelCacheManager = new ModelCacheManager(modelConfig, restConfig); + Element modelElement = modelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE, CONNECTOR_MODEL_ID)); + assertNotNull("Failed to retrieve any models from the server!", modelElement); + assertEquals("Failed to retrieve the correct model from the server!", "model", modelElement.getName()); + } + + @Test + public void testReadInvalidModelFromRestClient() throws ValidationServiceException { + ModelCacheManager modelCacheManager = new ModelCacheManager(modelConfig, restConfig); + String modelId = "non-existent-model-id"; + + assertNull("Invalid model ID should return null!", + modelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE, modelId))); + } + + @Test + public void testReadModelFromCache() throws ValidationServiceException { + ModelCacheManager modelCacheManager = new ModelCacheManager(modelConfig, restConfig); + + // Put a test element into the cache + modelCacheManager.put(new ModelId(MODEL_ID_ATTRIBUTE, CONNECTOR_MODEL_ID), new DefaultElement("test")); + Element modelElement = modelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE, CONNECTOR_MODEL_ID)); + + assertEquals("Failed to retrieve model from cache!", "test", modelElement.getName()); + } + + @Test + public void testCacheExpiry() throws ValidationServiceException { + ModelCacheManager modelCacheManager = new ModelCacheManager(modelConfig, restConfig); + String testModelId = "test-model-id"; + + // Test cache expiry time is set to 1 second in the test config. + // Put a test element into the cache manually. + modelCacheManager.put(new ModelId(MODEL_ID_ATTRIBUTE, testModelId), new DefaultElement("test")); + // Get try to get the element from the cache immediately. + Element modelElement = modelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE, testModelId)); + // Should not have expired yet. + assertEquals("Failed to retrieve model from cache!", "test", modelElement.getName()); + + // wait for the cache to expire. + try { + TimeUnit.MILLISECONDS.sleep(2500); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + + // Now when we try to get it again it should have expired and thus the cache should try to retrieve the model + // from the server using the test model id, which should return null. + assertNull("Invalid model ID should return null!", + modelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE, testModelId))); + } + + @Test + public void testReadModelFromFile() throws ValidationServiceException { + ModelCacheManager modelCacheManager = new ModelCacheManager(modelConfig, fileBasedRestConfig); + Element modelElement = modelCacheManager.get(new ModelId(MODEL_ID_ATTRIBUTE, CONNECTOR_MODEL_ID)); + assertNotNull("Model ID not found in cache!", modelElement); + assertEquals("Failed to retrieve model from server!", "model", modelElement.getName()); + } +} diff --git a/src/integration-test/java/org/onap/aai/validation/itest/ITestStartupServlet.java b/src/integration-test/java/org/onap/aai/validation/itest/ITestStartupServlet.java new file mode 100644 index 0000000..9d016a5 --- /dev/null +++ b/src/integration-test/java/org/onap/aai/validation/itest/ITestStartupServlet.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.itest; + +import javax.inject.Inject; +import org.junit.Before; +import org.onap.aai.validation.config.TopicConfig; +import org.onap.aai.validation.config.TopicConfig.Topic; +import org.onap.aai.validation.itest.util.TopicUtils; +import org.springframework.test.context.ContextConfiguration; + +//@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"classpath:itest-validation-service-beans.xml"}) +public class ITestStartupServlet { + + enum TestData { + // @formatter:off + VSERVER ("rule-driven-validator/test_events/vserver-create-event.json"); + + private String filename; + TestData(String filename) {this.filename = filename;} + public String getFilename() {return this.filename;} + // @formatter:on + } + + @Inject + private TopicConfig topicConfig; + + @Before + public void setUp() throws Exception { + // Consume any existing messages on the Event Bus before running each test. + for (Topic topic : topicConfig.getConsumerTopics()) { + TopicUtils.consumeEventBusMessage(topic); + } + + for (Topic topic : topicConfig.getPublisherTopics()) { + TopicUtils.consumeEventBusMessage(topic); + } + } + +} diff --git a/src/integration-test/java/org/onap/aai/validation/itest/ITestValidationService.java b/src/integration-test/java/org/onap/aai/validation/itest/ITestValidationService.java new file mode 100644 index 0000000..24fd35a --- /dev/null +++ b/src/integration-test/java/org/onap/aai/validation/itest/ITestValidationService.java @@ -0,0 +1,58 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.itest; + +import javax.inject.Inject; +import org.junit.Before; +import org.onap.aai.validation.config.TopicConfig; +import org.onap.aai.validation.config.TopicConfig.Topic; +import org.onap.aai.validation.itest.util.TopicUtils; +import org.springframework.test.context.ContextConfiguration; + +//@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"classpath:itest-validation-service-beans.xml"}) +public class ITestValidationService { + + enum TestData { + // @formatter:off + VSERVER ("rule-driven-validator/test_events/vserver-create-event.json"), + VSERVER_INVALID_DOMAIN ("events/vserver-create-event-invalid-domain.json"), + VSERVER_INVALID_EVENTTYPE ("events/vserver-create-event-invalid-eventtype.json"); + + private String filename; + TestData(String filename) {this.filename = filename;} + public String getFilename() {return this.filename;} + // @formatter:on + } + + + @Inject + private TopicConfig topicConfig; + + @Before + public void setUp() throws Exception { // NOSONAR + // Consume any existing messages on the Event Bus before running each test. + for (Topic topic : topicConfig.getConsumerTopics()) { + TopicUtils.consumeEventBusMessage(topic); + } + + for (Topic topic : topicConfig.getPublisherTopics()) { + TopicUtils.consumeEventBusMessage(topic); + } + } +} diff --git a/src/integration-test/java/org/onap/aai/validation/itest/ITestValidator.java b/src/integration-test/java/org/onap/aai/validation/itest/ITestValidator.java new file mode 100644 index 0000000..571a78f --- /dev/null +++ b/src/integration-test/java/org/onap/aai/validation/itest/ITestValidator.java @@ -0,0 +1,142 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.itest; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +import com.google.gson.JsonSyntaxException; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.List; +import javax.inject.Inject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.aai.validation.controller.ValidationController; +import org.onap.aai.validation.controller.ValidationController.Result; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.logging.LogHelper; +import org.onap.aai.validation.logging.LogReader; +import org.onap.aai.validation.publisher.MockEventPublisher; +import org.onap.aai.validation.ruledriven.validator.TestRuleDrivenValidator; +import org.onap.aai.validation.services.ValidateServiceImpl; +import org.onap.aai.validation.test.util.TestEntity; +import org.onap.aai.validation.test.util.ValidationResultIsEqual; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Integration test using a mocked message publisher which compares the actual validation result with an expected + * result. This test invokes the validation controller directly. + */ +@RunWith(SpringJUnit4ClassRunner.class) +@TestPropertySource(properties = {"schemaIngestPropLoc = src/test/resources/oxm-reader/schemaIngest.properties"}) +@ContextConfiguration(locations = {"classpath:" + ITestValidator.TEST_FOLDER + "/itest-mock-validator-beans.xml"}) +public class ITestValidator { + + static { + System.setProperty("AJSC_HOME", "."); + } + + public static final String TEST_FOLDER = "mock-validator-beans"; + private static final String SYSTEM_TEST_FOLDER = "system_test"; + + @Inject + ValidationController validationController; + + @Inject + MockEventPublisher messagePublisher; + + @Before + public void setUp() throws ValidationServiceException { + validationController.initialise(); + } + + /** + * @throws ValidationServiceException + */ + @Test + public void testValidateRuleDrivenSystemTestInstances() throws ValidationServiceException { + testEntities("/data/rule-driven", "/results/expected/rule-driven"); + } + + /** + * @throws ValidationServiceException + */ + @Test + public void testValidateModelDrivenSystemTestInstances() throws ValidationServiceException { + testEntities("/data/model-driven", "/results/expected/model-driven"); + } + + /** + * @param inputDataPath + * @param resultsDataPath + * @throws ValidationServiceException + */ + private void testEntities(String inputDataPath, String resultsDataPath) throws ValidationServiceException { + try { + List testEntities = + TestRuleDrivenValidator.getEntities(SYSTEM_TEST_FOLDER, inputDataPath, resultsDataPath); + for (TestEntity entity : testEntities) { + testValidation(entity); + } + } catch (URISyntaxException | IOException e) { + throw new ValidationServiceException(ValidationServiceError.RULE_EXECUTION_ERROR, e); + } + } + + /** + * @param entity + * @throws ValidationServiceException + * @throws IOException + */ + private void testValidation(TestEntity entity) throws ValidationServiceException, IOException { + LogReader errorReader = new LogReader(LogHelper.getLogDirectory(), "error"); + + try { + messagePublisher.setTestEntity(entity); + messagePublisher.setTestDescription(entity.inputFile.getAbsolutePath()); + Result result = validationController.execute(entity.getJson(), "itest"); + assertThat("Message publishing error: success response", messagePublisher.processedSuccessfully(), + is(true)); + if (result.getValidationResults().isEmpty()) { + assertThat(entity.expectedResultsFile, entity.getExpectedValidationResult(), is(nullValue())); + if (entity.expectsError()) { + String expectedErrorMessage = entity.getExpectedErrorMessage(); + if (!expectedErrorMessage.contains(ValidateServiceImpl.DEFAULT_MESSAGE_FOR_FILTERED_EVENTS)) { + String s = errorReader.getNewLines(); + assertThat(s, is(notNullValue())); + assertThat(entity.inputFile.toString(), s, containsString(expectedErrorMessage)); + } + } + } else { + assertThat(result.getValidationResults().get(0), + is(ValidationResultIsEqual.equalTo(entity.getExpectedValidationResult()))); + } + } catch (JsonSyntaxException | URISyntaxException | IOException e) { + throw new ValidationServiceException(ValidationServiceError.RULE_EXECUTION_ERROR, e); + } + } + +} diff --git a/src/integration-test/java/org/onap/aai/validation/itest/ITestValidatorHttpInterface.java b/src/integration-test/java/org/onap/aai/validation/itest/ITestValidatorHttpInterface.java new file mode 100644 index 0000000..6fde308 --- /dev/null +++ b/src/integration-test/java/org/onap/aai/validation/itest/ITestValidatorHttpInterface.java @@ -0,0 +1,132 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.itest; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.List; +import javax.inject.Inject; +import javax.ws.rs.core.Response.Status; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.aai.validation.controller.ValidationController; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.publisher.MockEventPublisher; +import org.onap.aai.validation.result.ValidationResult; +import org.onap.aai.validation.ruledriven.validator.TestRuleDrivenValidator; +import org.onap.aai.validation.services.ValidateService; +import org.onap.aai.validation.services.ValidateServiceImpl; +import org.onap.aai.validation.test.util.TestEntity; +import org.onap.aai.validation.test.util.ValidationResultIsEqual; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Integration test using a mocked message publisher which compares the actual validation result with an expected + * result. This test invokes the validation controller directly. + */ +@RunWith(SpringJUnit4ClassRunner.class) +@TestPropertySource(properties = {"schemaIngestPropLoc = src/test/resources/oxm-reader/schemaIngest.properties"}) +@ContextConfiguration( + locations = {"classpath:" + ITestValidatorHttpInterface.TEST_FOLDER + "/itest-mock-validator-beans.xml"}) +public class ITestValidatorHttpInterface { + public static final String TEST_FOLDER = "mock-validator-beans"; + private static final String SYSTEM_TEST_FOLDER = "system_test"; + + private ValidateService httpService; + + @Inject + ValidationController validationController; + + @Inject + MockEventPublisher messagePublisher; + + static { + System.setProperty("AJSC_HOME", "."); + } + + @Before + public void setUp() throws ValidationServiceException { + validationController.initialise(); + httpService = new ValidateServiceImpl(validationController, null); // Added this as part of a hotfix. Needs + // proper handling. + } + + /** + * @throws ValidationServiceException + */ + @Test + public void testValidateRuleDrivenSystemTestInstances() throws ValidationServiceException { + testEntities("/data/rule-driven", "/results/expected/rule-driven"); + } + + /** + * @param inputDataPath + * @param resultsDataPath + * @throws ValidationServiceException + */ + private void testEntities(String inputDataPath, String resultsDataPath) throws ValidationServiceException { + try { + List testEntities = + TestRuleDrivenValidator.getEntities(SYSTEM_TEST_FOLDER, inputDataPath, resultsDataPath); + for (TestEntity entity : testEntities) { + testValidation(entity); + } + } catch (URISyntaxException e) { + throw new ValidationServiceException(ValidationServiceError.RULE_EXECUTION_ERROR, e); + } + } + + /** + * @param entity + * @throws ValidationServiceException + */ + private void testValidation(TestEntity entity) throws ValidationServiceException { + try { + messagePublisher.setTestEntity(entity); + messagePublisher.setTestDescription(entity.inputFile.getAbsolutePath()); + + // Invoke the HTTP interface directly + ResponseEntity response = httpService.validate(entity.getJson()); + assertThat("Message publishing error for " + entity.inputFile, messagePublisher.processedSuccessfully(), + is(true)); + + if (response.getStatusCodeValue() == Status.OK.getStatusCode()) { + String responseText = response.getBody(); + JsonObject jsonObject = new JsonParser().parse(responseText).getAsJsonObject(); + assertThat(ValidationResult.fromJson(jsonObject.toString()), + is(ValidationResultIsEqual.equalTo(entity.getExpectedValidationResult()))); + } else { + // Add tests (expected results) for sending malformed JSON, multiple entities, etc. + } + } catch (JsonSyntaxException | URISyntaxException | IOException e) { + throw new ValidationServiceException(ValidationServiceError.RULE_EXECUTION_ERROR, e); + } + } + +} diff --git a/src/integration-test/java/org/onap/aai/validation/itest/util/TopicUtils.java b/src/integration-test/java/org/onap/aai/validation/itest/util/TopicUtils.java new file mode 100644 index 0000000..298b9a1 --- /dev/null +++ b/src/integration-test/java/org/onap/aai/validation/itest/util/TopicUtils.java @@ -0,0 +1,106 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.itest.util; + +import org.onap.aai.event.client.DMaaPEventConsumer; +import org.onap.aai.event.client.DMaaPEventPublisher; +import org.onap.aai.validation.config.TopicConfig.Topic; +import com.google.common.collect.Iterators; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class TopicUtils { + + TopicUtils() { + // Deliberately empty + } + + /** + * Queries the topics for the specified seconds until the matching string message is found. Returns true if a + * message is found, false if not found. + * + * @param maxSeconds + * @param regex + * @param topics + * @return + * @throws Exception + */ + public static boolean checkEverySecondForMessageOnTopics(int maxSeconds, String regex, List topics) + throws Exception { + for (int i = 0; i < maxSeconds; i++) { + TimeUnit.SECONDS.sleep(1); + + Collection messages = new ArrayList<>(); + for (Topic topic : topics) { + Iterators.addAll(messages, consumeEventBusMessage(topic).iterator()); + } + // Check that the messages have been consumed. + for (String message : messages) { + if (message.matches(regex)) { + return true; + } + } + } + return false; + } + + /** + * @param maxSeconds + * @param topics + * @return + * @throws Exception + */ + public static boolean checkEverySecondForNoMessageOnTopics(int maxSeconds, List topics) throws Exception { + boolean noMessageOnTopic = true; + // any string pattern + if (checkEverySecondForMessageOnTopics(maxSeconds, "(.*)", topics)) { + noMessageOnTopic = false; + } + return noMessageOnTopic; + } + + /** + * @param topic + * @return + * @throws Exception + */ + public static Iterable consumeEventBusMessage(Topic topic) throws Exception { + DMaaPEventConsumer consumer = new DMaaPEventConsumer(topic.getHost(), topic.getName(), topic.getUsername(), + topic.getPassword(), topic.getConsumerGroup(), topic.getConsumerId(), + DMaaPEventConsumer.DEFAULT_MESSAGE_WAIT_TIMEOUT, DMaaPEventConsumer.DEFAULT_MESSAGE_LIMIT, + topic.getTransportType()); + return consumer.consume(); + } + + /** + * @param messages + * @param topic + * @return + * @throws Exception + */ + public static int publishEventBusMessage(Collection messages, Topic topic) throws Exception { // NOSONAR + DMaaPEventPublisher publisher = new DMaaPEventPublisher(topic.getHost(), topic.getName(), topic.getUsername(), + topic.getPassword(), DMaaPEventPublisher.DEFAULT_BATCH_SIZE, DMaaPEventPublisher.DEFAULT_BATCH_AGE, + DMaaPEventPublisher.DEFAULT_BATCH_DELAY, topic.getTransportType()); + int sent = publisher.sendSync(topic.getPartition(), messages); + publisher.close(); + return sent; + } +} diff --git a/src/integration-test/resources/aai-environment.properties b/src/integration-test/resources/aai-environment.properties new file mode 100644 index 0000000..463a2b0 --- /dev/null +++ b/src/integration-test/resources/aai-environment.properties @@ -0,0 +1,31 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END===================================================== + +# This file is used by various tests (src/test and src/integration-test) as it loaded from the classpath +host=localhost +port=8443 +httpProtocol=file +trustStorePath=src/main/resources/authentication/tomcat_keystore +trustStorePassword.x=70c87528c88dcd9f9c2558d30e817868 +keyStorePath=src/main/resources/authentication/aai-client-cert.p12 +keyStorePassword.x=70c87528c88dcd9f9c2558d30e817868 +keyManagerFactoryAlgorithm=SunX509 +keyStoreType=PKCS12 +securityProtocol=TLS +connectionTimeout=5000 +readTimeout=1000 + +baseModelURI=src/test/resources/model-validation/instance-validator/all-models.xml \ No newline at end of file diff --git a/src/integration-test/resources/authentication/aai-client-cert.p12 b/src/integration-test/resources/authentication/aai-client-cert.p12 new file mode 100644 index 0000000..292efb7 Binary files /dev/null and b/src/integration-test/resources/authentication/aai-client-cert.p12 differ diff --git a/src/integration-test/resources/authentication/aai_keystore b/src/integration-test/resources/authentication/aai_keystore new file mode 100644 index 0000000..3eef135 Binary files /dev/null and b/src/integration-test/resources/authentication/aai_keystore differ diff --git a/src/integration-test/resources/authentication/amdocs_lab_keystore b/src/integration-test/resources/authentication/amdocs_lab_keystore new file mode 100644 index 0000000..52ecf1f Binary files /dev/null and b/src/integration-test/resources/authentication/amdocs_lab_keystore differ diff --git a/src/integration-test/resources/authentication/client-cert-onap.p12 b/src/integration-test/resources/authentication/client-cert-onap.p12 new file mode 100644 index 0000000..dbf4fca Binary files /dev/null and b/src/integration-test/resources/authentication/client-cert-onap.p12 differ diff --git a/src/integration-test/resources/authentication/tomcat_keystore b/src/integration-test/resources/authentication/tomcat_keystore new file mode 100644 index 0000000..efa01f8 Binary files /dev/null and b/src/integration-test/resources/authentication/tomcat_keystore differ diff --git a/src/integration-test/resources/event-polling/topic-aai-data-export.properties b/src/integration-test/resources/event-polling/topic-aai-data-export.properties new file mode 100644 index 0000000..dba912e --- /dev/null +++ b/src/integration-test/resources/event-polling/topic-aai-data-export.properties @@ -0,0 +1,24 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +aai-data-export.name=AAI-DATA-EXPORT +aai-data-export.host=130.9.133.19 +aai-data-export.username=EbsRgHJ2SuLuM2Lp +aai-data-export.password=7347c3ef253772d7e2b8e73b1a7ed4f751b730c692df6d1c25e96e352bffd11b +aai-data-export.publisher.partition=1 +aai-data-export.consumer.group=model-driven-validator +aai-data-export.consumer.id=0 +aai-data-export.transport.type=HTTPAUTH \ No newline at end of file diff --git a/src/integration-test/resources/event-polling/topic-aai-data-integrity.properties b/src/integration-test/resources/event-polling/topic-aai-data-integrity.properties new file mode 100644 index 0000000..f3b2f68 --- /dev/null +++ b/src/integration-test/resources/event-polling/topic-aai-data-integrity.properties @@ -0,0 +1,24 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +aai-data-integrity.name=AAI-DATA-INTEGRITY +aai-data-integrity.host=130.9.133.19 +aai-data-integrity.username=EbsRgHJ2SuLuM2Lp +aai-data-integrity.password=7347c3ef253772d7e2b8e73b1a7ed4f751b730c692df6d1c25e96e352bffd11b +aai-data-integrity.publisher.partition=1 +aai-data-integrity.consumer.group=model-driven-validator +aai-data-integrity.consumer.id=0 +aai-data-integrity.transport.type=HTTPAUTH \ No newline at end of file diff --git a/src/integration-test/resources/event-polling/topic-aai-event.properties b/src/integration-test/resources/event-polling/topic-aai-event.properties new file mode 100644 index 0000000..d273ae3 --- /dev/null +++ b/src/integration-test/resources/event-polling/topic-aai-event.properties @@ -0,0 +1,24 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +aai-event.name=AAI-EVENT +aai-event.host=130.9.133.19 +aai-event.username=EbsRgHJ2SuLuM2Lp +aai-event.password=7347c3ef253772d7e2b8e73b1a7ed4f751b730c692df6d1c25e96e352bffd11b +aai-event.publisher.partition=1 +aai-event.consumer.group=model-driven-validator +aai-event.consumer.id=0 +aai-event.transport.type=HTTPAUTH \ No newline at end of file diff --git a/src/integration-test/resources/events/vserver-create-event-invalid-domain.json b/src/integration-test/resources/events/vserver-create-event-invalid-domain.json new file mode 100644 index 0000000..80158b3 --- /dev/null +++ b/src/integration-test/resources/events/vserver-create-event-invalid-domain.json @@ -0,0 +1,163 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "invalidDomain", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v7", + "action": "CREATE", + "entity-type": "vserver", + "top-entity-type": "cloud-region", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666" + }, + "entity": { + "cloud-owner": "att-aic", + "cloud-region-id": "AAIAIC25", + "tenants": { + "tenant": [ + { + "tenant-id": "example-tenant-id-val-88551", + "tenant-name": "example-tenant-name-val-88551", + "vservers": { + "vserver": [ + { + "vserver-id": "example-vserver-id-val-34666", + "vserver-name": "example-vserver-name-val-34666", + "vserver-name2": "example-vserver-name2-val-34666", + "prov-status": "PREPROV", + "vserver-selflink": "example-vserver-selflink-val-34666", + "in-maint": true, + "is-closed-loop-disabled": true, + "resource-version": "1464193654", + "volumes": { + "volume": [ + { + "volume-id": "example-volume-id-val-79195", + "volume-selflink": "example-volume-selflink-val-79195", + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + }, + "relationship-list": { + + }, + "l-interfaces": { + "l-interface": [ + { + "interface-name": "example-interface-name-val-25679", + "interface-role": "example-interface-role-val-25679", + "v6-wan-link-ip": "example-v6-wan-link-ip-val-25679", + "selflink": "example-selflink-val-25679", + "interface-id": "example-interface-id-val-25679", + "macaddr": "example-macaddr-val-25679", + "network-name": "example-network-name-val-25679", + "resource-version": "1464193654", + "vlans": { + "vlan": [ + { + "vlan-interface": "example-vlan-interface-val-28675", + "vlan-id-inner": 22278797, + "vlan-id-outer": 22278797, + "resource-version": "1464193654", + "speed-value": "example-speed-value-val-28675", + "speed-units": "example-speed-units-val-28675", + "vlan-description": "example-vlan-description-val-28675", + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-39271", + "l3-interface-ipv4-prefix-length": 78868308, + "vlan-id-inner": 78868308, + "vlan-id-outer": 78868308, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-4005", + "l3-interface-ipv6-prefix-length": 78340763, + "vlan-id-inner": 78340763, + "vlan-id-outer": 78340763, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + } + ] + }, + "sriov-vfs": { + "sriov-vf": [ + { + "pci-id": "example-pci-id-val-85354", + "vf-vlan-filter": "example-vf-vlan-filter-val-85354", + "vf-mac-filter": "example-vf-mac-filter-val-85354", + "vf-vlan-strip": true, + "vf-vlan-anti-spoof-check": true, + "vf-mac-anti-spoof-check": true, + "vf-mirrors": "example-vf-mirrors-val-85354", + "vf-broadcast-allow": true, + "vf-unknown-multicast-allow": true, + "vf-unknown-unicast-allow": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + }, + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-21446", + "l3-interface-ipv4-prefix-length": 71127022, + "vlan-id-inner": 71127022, + "vlan-id-outer": 71127022, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-88071", + "l3-interface-ipv6-prefix-length": 55080281, + "vlan-id-inner": 55080281, + "vlan-id-outer": 55080281, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + } + ] + } + } + ] + } + } + ] + } + } +} \ No newline at end of file diff --git a/src/integration-test/resources/events/vserver-create-event-invalid-eventtype.json b/src/integration-test/resources/events/vserver-create-event-invalid-eventtype.json new file mode 100644 index 0000000..d931739 --- /dev/null +++ b/src/integration-test/resources/events/vserver-create-event-invalid-eventtype.json @@ -0,0 +1,163 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "INVALID-EVENTTYPE", + "version": "v7", + "action": "CREATE", + "entity-type": "vserver", + "top-entity-type": "cloud-region", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666" + }, + "entity": { + "cloud-owner": "att-aic", + "cloud-region-id": "AAIAIC25", + "tenants": { + "tenant": [ + { + "tenant-id": "example-tenant-id-val-88551", + "tenant-name": "example-tenant-name-val-88551", + "vservers": { + "vserver": [ + { + "vserver-id": "example-vserver-id-val-34666", + "vserver-name": "example-vserver-name-val-34666", + "vserver-name2": "example-vserver-name2-val-34666", + "prov-status": "PREPROV", + "vserver-selflink": "example-vserver-selflink-val-34666", + "in-maint": true, + "is-closed-loop-disabled": true, + "resource-version": "1464193654", + "volumes": { + "volume": [ + { + "volume-id": "example-volume-id-val-79195", + "volume-selflink": "example-volume-selflink-val-79195", + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + }, + "relationship-list": { + + }, + "l-interfaces": { + "l-interface": [ + { + "interface-name": "example-interface-name-val-25679", + "interface-role": "example-interface-role-val-25679", + "v6-wan-link-ip": "example-v6-wan-link-ip-val-25679", + "selflink": "example-selflink-val-25679", + "interface-id": "example-interface-id-val-25679", + "macaddr": "example-macaddr-val-25679", + "network-name": "example-network-name-val-25679", + "resource-version": "1464193654", + "vlans": { + "vlan": [ + { + "vlan-interface": "example-vlan-interface-val-28675", + "vlan-id-inner": 22278797, + "vlan-id-outer": 22278797, + "resource-version": "1464193654", + "speed-value": "example-speed-value-val-28675", + "speed-units": "example-speed-units-val-28675", + "vlan-description": "example-vlan-description-val-28675", + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-39271", + "l3-interface-ipv4-prefix-length": 78868308, + "vlan-id-inner": 78868308, + "vlan-id-outer": 78868308, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-4005", + "l3-interface-ipv6-prefix-length": 78340763, + "vlan-id-inner": 78340763, + "vlan-id-outer": 78340763, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + } + ] + }, + "sriov-vfs": { + "sriov-vf": [ + { + "pci-id": "example-pci-id-val-85354", + "vf-vlan-filter": "example-vf-vlan-filter-val-85354", + "vf-mac-filter": "example-vf-mac-filter-val-85354", + "vf-vlan-strip": true, + "vf-vlan-anti-spoof-check": true, + "vf-mac-anti-spoof-check": true, + "vf-mirrors": "example-vf-mirrors-val-85354", + "vf-broadcast-allow": true, + "vf-unknown-multicast-allow": true, + "vf-unknown-unicast-allow": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + }, + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-21446", + "l3-interface-ipv4-prefix-length": 71127022, + "vlan-id-inner": 71127022, + "vlan-id-outer": 71127022, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-88071", + "l3-interface-ipv6-prefix-length": 55080281, + "vlan-id-inner": 55080281, + "vlan-id-outer": 55080281, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + } + ] + } + } + ] + } + } + ] + } + } +} \ No newline at end of file diff --git a/src/integration-test/resources/itest-topic-config-beans.xml b/src/integration-test/resources/itest-topic-config-beans.xml new file mode 100644 index 0000000..3c1ac4f --- /dev/null +++ b/src/integration-test/resources/itest-topic-config-beans.xml @@ -0,0 +1,48 @@ + + + + + + + + + + aai-event + aai-data-export + + + + + aai-data-integrity + + + + + + + + + classpath:event-polling/topic-aai-event.properties + classpath:event-polling/topic-aai-data-export.properties + classpath:event-polling/topic-aai-data-integrity.properties + + + + \ No newline at end of file diff --git a/src/integration-test/resources/itest-validation-service-beans.xml b/src/integration-test/resources/itest-validation-service-beans.xml new file mode 100644 index 0000000..3bb189f --- /dev/null +++ b/src/integration-test/resources/itest-validation-service-beans.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/integration-test/resources/mock-validator-beans/itest-mock-validator-beans.xml b/src/integration-test/resources/mock-validator-beans/itest-mock-validator-beans.xml new file mode 100644 index 0000000..10e4510 --- /dev/null +++ b/src/integration-test/resources/mock-validator-beans/itest-mock-validator-beans.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/integration-test/resources/model-cache-manager/aai-environment.properties b/src/integration-test/resources/model-cache-manager/aai-environment.properties new file mode 100644 index 0000000..8568e84 --- /dev/null +++ b/src/integration-test/resources/model-cache-manager/aai-environment.properties @@ -0,0 +1,34 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +# Connect to an A&AI instance with a self-signed cert +host=10.247.40.18 +port=8443 +httpProtocol=https + +keyStorePath=src/integration-test/resources/authentication/client-cert-onap.p12 +keyStorePassword.x=dfcfd1003bdde18de8efea3c8661510e + +trustStorePath=src/integration-test/resources/authentication/amdocs_lab_keystore +trustStorePassword.x=d51d7ede93ce420aef10b5f463677f10 + +keyManagerFactoryAlgorithm=SunX509 +keyStoreType=PKCS12 +securityProtocol=TLS +connectionTimeout=5000 +readTimeout=1000 + +baseModelURI=/aai/v11/service-design-and-creation/models/model diff --git a/src/integration-test/resources/model-cache-manager/itest-validation-service-beans.xml b/src/integration-test/resources/model-cache-manager/itest-validation-service-beans.xml new file mode 100644 index 0000000..646e6d7 --- /dev/null +++ b/src/integration-test/resources/model-cache-manager/itest-validation-service-beans.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/integration-test/resources/model-cache-manager/validation-service.properties b/src/integration-test/resources/model-cache-manager/validation-service.properties new file mode 100644 index 0000000..d60385e --- /dev/null +++ b/src/integration-test/resources/model-cache-manager/validation-service.properties @@ -0,0 +1,27 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +topic.publish.enable=true +topic.publish.retries=3 +topic.consume.enable=true +topic.consume.polling.interval.seconds=3 + +event.domain=devINT1 +event.action.exclude=DELETE +event.type.rule=AAI-EVENT,AAI-DATA-EXPORT-API +event.type.model=AAI-DATA-EXPORT-NQ + +model.cache.expirySeconds=2 \ No newline at end of file diff --git a/src/integration-test/resources/model-instance-mapping.json_conf b/src/integration-test/resources/model-instance-mapping.json_conf new file mode 100644 index 0000000..12d39ea --- /dev/null +++ b/src/integration-test/resources/model-instance-mapping.json_conf @@ -0,0 +1,28 @@ +[ + { + "mappingType": "RELATIONSHIP", + "model": { + "root": "model-elements/model-element", + "id": "relationship-list/relationship/relationship-data/relationship-value[../relationship-key/text()='model.model-name-version-id']", + "value": "relationship-list/relationship/related-to-property/property-value[../property-key/text()='model.model-name']", + "filter": { + "path": "relationship-list/relationship/related-to-property/property-value[../property-key/text()='model.model-type']", + "valid": ["widget"] + } + }, + "instance": { + "origin": "$.inventory-response-item[0]", + "root": "$.inventory-response-items.inventory-response-item[*]" + } + }, + { + "mappingType": "ATTRIBUTE", + "model": { + "value": "metadata/metadatum/metaname" + }, + "instance": { + "origin": "$.inventory-response-item[0]", + "value": "$..extra-properties.metadatum[*].metaname" + } + } +] diff --git a/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-excess-metadata.json b/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-excess-metadata.json new file mode 100644 index 0000000..f971ede --- /dev/null +++ b/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-excess-metadata.json @@ -0,0 +1,421 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-DATA-EXPORT-NQ", + "version": "v9", + "action": "CREATE", + "entity-type": "connector", + "top-entity-type": "connector", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v9/business/connectors/connector/100559" + }, + "entity": { + "inventory-response-item": [ + { + "model-name": "NetBond WAN Connector v0.1", + "connector": { + "resource-instance-id": "100559", + "resource-version": "1465571381", + "persona-model-id": "dc700a83-c507-47d9-b775-1fdfcdd5f9eb", + "persona-model-version": "0.1" + }, + "extra-properties": { + "metadatum": [ + { + "metaname": "vpn-id", + "metaval": "vpn-id value 1", + "resource-version": "1466418452" + }, + { + "metaname": "unexpected", + "metaval": "unexpected value 1", + "resource-version": "1466418452" + }, + { + "metaname": "null", + "metaval": "null", + "resource-version": "1466418452" + } + ] + }, + "inventory-response-items": { + "inventory-response-item": [ + { + "virtual-data-center": { + "vdc-id": "15001220", + "vdc-name": "SAN_DIEGO_CA01", + "resource-version": "1465571382" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "sn6ca391ve2-xe-10/2/3.117|sn4ca01pbg", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "sn4ca01pbg", + "in-maint": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca391ve2-ae6.1322|dbzx0003v", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-2883", + "vnf-name": "dbzx0004v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978155" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca392ve2-ae6.1322|dbzx0003v", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-2883", + "vnf-name": "dbzx0004v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978155" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca392ve2-ae6.1927|asbg0003v", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-9320", + "vnf-name": "asbg0003v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.193.152.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "sn6ca392ve2-xe-10/2/3.117|sn4ca01pbg", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "sn4ca01pbg", + "in-maint": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca391ve2-ae6.1927|asbg0003v", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-9320", + "vnf-name": "asbg0003v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.193.152.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + } + ] + } + }, + { + "virtual-data-center": { + "vdc-id": "15001219", + "vdc-name": "ALPHARETTA_GA01", + "resource-version": "1465571380" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga392ve2-ae6.1322|dbzx0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-1883", + "vnf-name": "dbzx0003v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga391ve2-ae6.1322|dbzx0004v", + "link-type": "l2bridge", + "resource-version": "1465571379", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-1883", + "vnf-name": "dbzx0003v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga392ve2-ae6.1927|asbg0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-5305", + "vnf-name": "asbg0004v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.190.182.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978152" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "alrga391ve2-xe-10/2/3.117|ar4ga01pbg", + "link-type": "l2bridge", + "resource-version": "1465571379", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "ar4ga01pbg", + "in-maint": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga391ve2-ae6.1927|asbg0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-5305", + "vnf-name": "asbg0004v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.190.182.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978152" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "alrga392ve2-xe-10/2/3.117|ar4ga01pbg", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "ar4ga01pbg", + "in-maint": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + } + ] + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-missing-attribute.json b/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-missing-attribute.json new file mode 100644 index 0000000..129117d --- /dev/null +++ b/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-missing-attribute.json @@ -0,0 +1,416 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-DATA-EXPORT-NQ", + "version": "v9", + "action": "CREATE", + "entity-type": "connector", + "top-entity-type": "connector", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v9/business/connectors/connector/100559" + }, + "entity": { + "inventory-response-item": [ + { + "model-name": "NetBond WAN Connector v0.1", + "connector": { + "resource-instance-id": "100559", + "resource-version": "1465571381", + "persona-model-id": "dc700a83-c507-47d9-b775-1fdfcdd5f9eb", + "persona-model-version": "0.1" + }, + "extra-properties": { + "metadatum": [ + { + "metaname": "vpn-id", + "metaval": "vpn-id value 1", + "resource-version": "1466418452" + }, + { + "metaname": "unexpected", + "metaval": "unexpected value 1", + "resource-version": "1466418452" + } + ] + }, + "inventory-response-items": { + "inventory-response-item": [ + { + "virtual-data-center": { + "vdc-id": "15001220", + "vdc-name": "SAN_DIEGO_CA01", + "resource-version": "1465571382" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "sn6ca391ve2-xe-10/2/3.117|sn4ca01pbg", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "sn4ca01pbg", + "in-maint": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca391ve2-ae6.1322|dbzx0003v", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-2883", + "vnf-name": "dbzx0004v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978155" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca392ve2-ae6.1322|dbzx0003v", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-2883", + "vnf-name": "dbzx0004v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978155" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca392ve2-ae6.1927|asbg0003v", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-9320", + "vnf-name": "asbg0003v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.193.152.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "sn6ca392ve2-xe-10/2/3.117|sn4ca01pbg", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "sn4ca01pbg", + "in-maint": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca391ve2-ae6.1927|asbg0003v", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-9320", + "vnf-name": "asbg0003v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.193.152.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + } + ] + } + }, + { + "virtual-data-center": { + "vdc-id": "15001219", + "vdc-name": "ALPHARETTA_GA01", + "resource-version": "1465571380" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga392ve2-ae6.1322|dbzx0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-1883", + "vnf-name": "dbzx0003v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga391ve2-ae6.1322|dbzx0004v", + "link-type": "l2bridge", + "resource-version": "1465571379", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-1883", + "vnf-name": "dbzx0003v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga392ve2-ae6.1927|asbg0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-5305", + "vnf-name": "asbg0004v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.190.182.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978152" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "alrga391ve2-xe-10/2/3.117|ar4ga01pbg", + "link-type": "l2bridge", + "resource-version": "1465571379", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "ar4ga01pbg", + "in-maint": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga391ve2-ae6.1927|asbg0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-5305", + "vnf-name": "asbg0004v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.190.182.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978152" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "alrga392ve2-xe-10/2/3.117|ar4ga01pbg", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "ar4ga01pbg", + "in-maint": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + } + ] + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-no-metadata.json b/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-no-metadata.json new file mode 100644 index 0000000..d5e618d --- /dev/null +++ b/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-no-metadata.json @@ -0,0 +1,403 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-DATA-EXPORT-NQ", + "version": "v9", + "action": "CREATE", + "entity-type": "connector", + "top-entity-type": "connector", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v9/business/connectors/connector/100559" + }, + "entity": { + "inventory-response-item": [ + { + "model-name": "NetBond WAN Connector v0.1", + "connector": { + "resource-instance-id": "100559", + "resource-version": "1465571381", + "persona-model-id": "dc700a83-c507-47d9-b775-1fdfcdd5f9eb", + "persona-model-version": "0.1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "virtual-data-center": { + "vdc-id": "15001220", + "vdc-name": "SAN_DIEGO_CA01", + "resource-version": "1465571382" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "sn6ca391ve2-xe-10/2/3.117|sn4ca01pbg", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "sn4ca01pbg", + "in-maint": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca391ve2-ae6.1322|dbzx0003v", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-2883", + "vnf-name": "dbzx0004v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978155" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca392ve2-ae6.1322|dbzx0003v", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-2883", + "vnf-name": "dbzx0004v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978155" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca392ve2-ae6.1927|asbg0003v", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-9320", + "vnf-name": "asbg0003v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.193.152.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "sn6ca392ve2-xe-10/2/3.117|sn4ca01pbg", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "sn4ca01pbg", + "in-maint": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca391ve2-ae6.1927|asbg0003v", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-9320", + "vnf-name": "asbg0003v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.193.152.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + } + ] + } + }, + { + "virtual-data-center": { + "vdc-id": "15001219", + "vdc-name": "ALPHARETTA_GA01", + "resource-version": "1465571380" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga392ve2-ae6.1322|dbzx0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-1883", + "vnf-name": "dbzx0003v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga391ve2-ae6.1322|dbzx0004v", + "link-type": "l2bridge", + "resource-version": "1465571379", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-1883", + "vnf-name": "dbzx0003v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga392ve2-ae6.1927|asbg0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-5305", + "vnf-name": "asbg0004v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.190.182.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978152" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "alrga391ve2-xe-10/2/3.117|ar4ga01pbg", + "link-type": "l2bridge", + "resource-version": "1465571379", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "ar4ga01pbg", + "in-maint": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga391ve2-ae6.1927|asbg0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-5305", + "vnf-name": "asbg0004v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.190.182.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978152" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "alrga392ve2-xe-10/2/3.117|ar4ga01pbg", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "ar4ga01pbg", + "in-maint": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + } + ] + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-no-model.json b/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-no-model.json new file mode 100644 index 0000000..313f934 --- /dev/null +++ b/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-no-model.json @@ -0,0 +1,58 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-DATA-EXPORT-NQ", + "version": "v9", + "action": "CREATE", + "entity-type": "connector", + "top-entity-type": "connector", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v9/business/connectors/connector/100559" + }, + "entity": { + "inventory-response-item": [ + { + "connector": { + "resource-instance-id": "c7611ebe-c324-48f1-8085-94aef0c12fd", + "resource-version": "1467975776", + "persona-model-id": "invalid-model-id", + "persona-model-version": "v1.0", + "widget-model-id": "example-widget-model-id-val-69486", + "widget-model-version": "v1.0" + }, + "extra-properties": { + "metadatum": [ + { + "metaname": "vpn-id", + "metaval": "vpn-id-value-1", + "resource-version": "1465990410" + }, + { + "metaname": "product", + "metaval": "product-value-1", + "resource-version": "1465990410" + } + ] + }, + "inventory-response-items": { + "inventory-response-item": [ + { + "virtual-data-center": { + "vdc-id": "vdc-01", + "vdc-name": "example-vdc-name-val-10107", + "resource-version": "1467975781" + }, + "extra-properties": { + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-valid.json b/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-valid.json new file mode 100644 index 0000000..68b4281 --- /dev/null +++ b/src/integration-test/resources/system_test/data/model-driven/connector/connector-create-valid.json @@ -0,0 +1,416 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-DATA-EXPORT-NQ", + "version": "v9", + "action": "CREATE", + "entity-type": "connector", + "top-entity-type": "connector", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v9/business/connectors/connector/100559" + }, + "entity": { + "inventory-response-item": [ + { + "model-name": "NetBond WAN Connector v0.1", + "connector": { + "resource-instance-id": "100559", + "resource-version": "1465571381", + "persona-model-id": "dc700a83-c507-47d9-b775-1fdfcdd5f9eb", + "persona-model-version": "0.1" + }, + "extra-properties": { + "metadatum": [ + { + "metaname": "vpn-id", + "metaval": "vpn-id-value-1", + "resource-version": "1465990410" + }, + { + "metaname": "product", + "metaval": "product-value-1", + "resource-version": "1465990410" + } + ] + }, + "inventory-response-items": { + "inventory-response-item": [ + { + "virtual-data-center": { + "vdc-id": "15001220", + "vdc-name": "SAN_DIEGO_CA01", + "resource-version": "1465571382" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "sn6ca391ve2-xe-10/2/3.117|sn4ca01pbg", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "sn4ca01pbg", + "in-maint": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca391ve2-ae6.1322|dbzx0003v", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-2883", + "vnf-name": "dbzx0004v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978155" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca392ve2-ae6.1322|dbzx0003v", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-2883", + "vnf-name": "dbzx0004v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978155" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca392ve2-ae6.1927|asbg0003v", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-9320", + "vnf-name": "asbg0003v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.193.152.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "sn6ca392ve2-xe-10/2/3.117|sn4ca01pbg", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "sn4ca01pbg", + "in-maint": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca391ve2-ae6.1927|asbg0003v", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-9320", + "vnf-name": "asbg0003v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.193.152.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + } + ] + } + }, + { + "virtual-data-center": { + "vdc-id": "15001219", + "vdc-name": "ALPHARETTA_GA01", + "resource-version": "1465571380" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga392ve2-ae6.1322|dbzx0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-1883", + "vnf-name": "dbzx0003v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga391ve2-ae6.1322|dbzx0004v", + "link-type": "l2bridge", + "resource-version": "1465571379", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-1883", + "vnf-name": "dbzx0003v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga392ve2-ae6.1927|asbg0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-5305", + "vnf-name": "asbg0004v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.190.182.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978152" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "alrga391ve2-xe-10/2/3.117|ar4ga01pbg", + "link-type": "l2bridge", + "resource-version": "1465571379", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "ar4ga01pbg", + "in-maint": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga391ve2-ae6.1927|asbg0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-5305", + "vnf-name": "asbg0004v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.190.182.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978152" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "alrga392ve2-xe-10/2/3.117|ar4ga01pbg", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "ar4ga01pbg", + "in-maint": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + } + ] + } + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-bad-network-name.json b/src/integration-test/resources/system_test/data/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-bad-network-name.json new file mode 100644 index 0000000..b28c5d8 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-bad-network-name.json @@ -0,0 +1,167 @@ +{ + "cambria.partition ": "AAI ", + "entity": { + "physical-location-id": "MTWNJZZZLCP", + "data-center-code": "mtznj-dc", + "complex-name": "mtznj", + "resource-version": "1463283799", + "physical-location-type": "CO", + "street1": "200 South Laurel Ave.", + "street2": "", + "city": "Middletown", + "state": "NJ", + "postal-code": "07748", + "country": "USA", + "region": "US", + "latitude": "40.395968", + "longitude": "-74.135344", + "elevation": "", + "lata": "224", + "ctag-pools": { + "ctag-pool": [{ + "target-pe": "mtznj301vr1", + "availability-zone-name": "mtznj-esx-az01", + "ctag-pool-purpose": "IPAG", + "ctag-values": "2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025", + "resource-version": "1455590484", + "relationship-list": { + "relationship": [{ + "related-to": "availability-zone", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/availability-zones/availability-zone/mtznj-esx-az01/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, { + "relationship-key": "availability-zone.availability-zone-name", + "relationship-value": "mtznj-esx-az01" + }] + }] + } + }, { + "target-pe": "VPESAT-mtznj401me6", + "availability-zone-name": "mtznj-esx-az01", + "ctag-pool-purpose": "VPE", + "ctag-values": "3001,3002,3003,3004,3005,3006,3007,3008,3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050", + "resource-version": "1455590484", + "relationship-list": { + "relationship": [{ + "related-to": "vpe", + "related-link": "https://135.16.121.249:8443/aai/v8/network/vpes/vpe/VPESAT-mtanjrsv126/", + "relationship-data": [{ + "relationship-key": "vpe.vnf-id", + "relationship-value": "VPESAT-mtanjrsv126" + }], + "related-to-property": [{ + "property-key": "vpe.vnf-name", + "property-value": "mtanjrsv126" + }] + }, { + "related-to": "availability-zone", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/availability-zones/availability-zone/mtznj-esx-az01/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, { + "relationship-key": "availability-zone.availability-zone-name", + "relationship-value": "mtznj-esx-az01" + }] + }] + } + }] + }, + "relationship-list": { + "relationship": [{ + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/mtznj101snd/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "mtznj101snd" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, { + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/mtznjtax101/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "mtznjtax101" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, { + "related-to": "vce", + "related-link": "https://135.16.121.249:8443/aai/v8/network/vces/vce/19a2ac02-bed0-4d84-a751-6dffffffffff/", + "relationship-data": [{ + "relationship-key": "vce.vnf-id", + "relationship-value": "19a2ac02-bed0-4d84-a751-6dffffffffff" + }], + "related-to-property": [{ + "property-key": "vce.vnf-name", + "property-value": "mtznj431vbc" + }] + }, { + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/mtznj125snd/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "mtznj125snd" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, { + "related-to": "oam-network", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/oam-networks/oam-network/ca084d91-ffff-ffff-a1bf-a8a7f1969f80/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, { + "relationship-key": "oam-network.network-uuid", + "relationship-value": "ca084d91-ffff-ffff-a1bf-a8a7f1969f80" + }], + "related-to-property": [{ + "property-key": "oam-network.network-name", + "property-value": "MARK-OAM-1323" + }] + }, { + "related-to": "availability-zone", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/availability-zones/availability-zone/mtznj-esx-az01/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, { + "relationship-key": "availability-zone.availability-zone-name", + "relationship-value": "mtznj-esx-az01" + }] + }] + } + }, + "event-header": { + "timestamp": "20161017-20:56:15:411", + "id": "20161017205615-c0e8aa29-dcf3-4267-9fd3-e508c271234", + "action": "UPDATE", + "domain": "devINT1", + "source-name": "ComplexTestData", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/network/newvces/newvce/7150963a-9054-4046-a285-a572edf2deb6", + "entity-type": "complex", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "complex", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-good-network-name.json b/src/integration-test/resources/system_test/data/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-good-network-name.json new file mode 100644 index 0000000..c1c5035 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-good-network-name.json @@ -0,0 +1,167 @@ +{ + "cambria.partition ": "AAI ", + "entity": { + "physical-location-id": "MTWNJZZZLCP", + "data-center-code": "mtznj-dc", + "complex-name": "mtznj", + "resource-version": "1463283799", + "physical-location-type": "CO", + "street1": "200 South Laurel Ave.", + "street2": "", + "city": "Middletown", + "state": "NJ", + "postal-code": "07748", + "country": "USA", + "region": "US", + "latitude": "40.395968", + "longitude": "-74.135344", + "elevation": "", + "lata": "224", + "ctag-pools": { + "ctag-pool": [{ + "target-pe": "mtznj301vr1", + "availability-zone-name": "mtznj-esx-az01", + "ctag-pool-purpose": "IPAG", + "ctag-values": "2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025", + "resource-version": "1455590484", + "relationship-list": { + "relationship": [{ + "related-to": "availability-zone", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/availability-zones/availability-zone/mtznj-esx-az01/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, { + "relationship-key": "availability-zone.availability-zone-name", + "relationship-value": "mtznj-esx-az01" + }] + }] + } + }, { + "target-pe": "VPESAT-mtznj401me6", + "availability-zone-name": "mtznj-esx-az01", + "ctag-pool-purpose": "VPE", + "ctag-values": "3001,3002,3003,3004,3005,3006,3007,3008,3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050", + "resource-version": "1455590484", + "relationship-list": { + "relationship": [{ + "related-to": "vpe", + "related-link": "https://135.16.121.249:8443/aai/v8/network/vpes/vpe/VPESAT-mtanjrsv126/", + "relationship-data": [{ + "relationship-key": "vpe.vnf-id", + "relationship-value": "VPESAT-mtanjrsv126" + }], + "related-to-property": [{ + "property-key": "vpe.vnf-name", + "property-value": "mtanjrsv126" + }] + }, { + "related-to": "availability-zone", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/availability-zones/availability-zone/mtznj-esx-az01/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, { + "relationship-key": "availability-zone.availability-zone-name", + "relationship-value": "mtznj-esx-az01" + }] + }] + } + }] + }, + "relationship-list": { + "relationship": [{ + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/mtznj101snd/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "mtznj101snd" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, { + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/mtznjtax101/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "mtznjtax101" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, { + "related-to": "vce", + "related-link": "https://135.16.121.249:8443/aai/v8/network/vces/vce/19a2ac02-bed0-4d84-a751-6dffffffffff/", + "relationship-data": [{ + "relationship-key": "vce.vnf-id", + "relationship-value": "19a2ac02-bed0-4d84-a751-6dffffffffff" + }], + "related-to-property": [{ + "property-key": "vce.vnf-name", + "property-value": "mtznj431vbc" + }] + }, { + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/mtznj125snd/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "mtznj125snd" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, { + "related-to": "oam-network", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/oam-networks/oam-network/ca084d91-ffff-ffff-a1bf-a8a7f1969f80/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, { + "relationship-key": "oam-network.network-uuid", + "relationship-value": "ca084d91-ffff-ffff-a1bf-a8a7f1969f80" + }], + "related-to-property": [{ + "property-key": "oam-network.network-name", + "property-value": "VLAN-OAM-1323" + }] + }, { + "related-to": "availability-zone", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/availability-zones/availability-zone/mtznj-esx-az01/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, { + "relationship-key": "availability-zone.availability-zone-name", + "relationship-value": "mtznj-esx-az01" + }] + }] + } + }, + "event-header": { + "timestamp": "20161017-20:56:15:411", + "id": "20161017205615-c0e8aa29-dcf3-4267-9fd3-e508c271234", + "action": "UPDATE", + "domain": "devINT1", + "source-name": "ComplexTestData", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/network/newvces/newvce/7150963a-9054-4046-a285-a572edf2deb6", + "entity-type": "complex", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "complex", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/edge-cases/empty-payload.json b/src/integration-test/resources/system_test/data/rule-driven/edge-cases/empty-payload.json new file mode 100644 index 0000000..e69de29 diff --git a/src/integration-test/resources/system_test/data/rule-driven/edge-cases/end-event.json b/src/integration-test/resources/system_test/data/rule-driven/edge-cases/end-event.json new file mode 100644 index 0000000..bfabb75 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/edge-cases/end-event.json @@ -0,0 +1,12 @@ +{ + "cambria.partition": "AAI", + "entity": { + + }, + "event-header": { + "timestamp": "", + "id": "", + "source-name": "", + "entity-type": "END-EVENT" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/edge-cases/missing-event-type.json b/src/integration-test/resources/system_test/data/rule-driven/edge-cases/missing-event-type.json new file mode 100644 index 0000000..cf9e536 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/edge-cases/missing-event-type.json @@ -0,0 +1,12 @@ +{ + "cambria.partition": "AAI", + "entity": { + + }, + "event-header": { + "timestamp": "", + "id": "", + "source-name": "", + "entity-type": "" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/edge-cases/plain-text-payload.json b/src/integration-test/resources/system_test/data/rule-driven/edge-cases/plain-text-payload.json new file mode 100644 index 0000000..980a0d5 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/edge-cases/plain-text-payload.json @@ -0,0 +1 @@ +Hello World! diff --git a/src/integration-test/resources/system_test/data/rule-driven/empty-ruleset/spike-pserver-create-update.json b/src/integration-test/resources/system_test/data/rule-driven/empty-ruleset/spike-pserver-create-update.json new file mode 100644 index 0000000..113d83f --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/empty-ruleset/spike-pserver-create-update.json @@ -0,0 +1,56 @@ +{ + "cambria.partition": "AAI", + "entity": [ + { + "transaction-id": "3b45dfa2-7a0a-47be-9b62-4jChYTSaDZd1", + "vertex": { + "schema-version": "v11", + "type": "pserver", + "key": "a5u3uo-4qpkw0-ba51-4jChYTSaDZd1", + "properties": { + "ptnii-equip-name": "fdsa", + "hostname": "mtanjasdf119snd", + "equip-type": "server-new", + "equip-vendor": "HP", + "equip-model": "DL380p-nd", + "in-maint": false, + "fqdn": "mtanjrsv119.mtanj.sbcglobal.net", + "purpose": "", + "ipv4-oam-address": "135.182.138.60", + "aai-node-type": "pserver" + } + }, + "operation": "CREATE", + "timestamp": 1519189272389 + }, + { + "transaction-id": "3b45dfa2-7a0a-47be-9b62-4jChYTSaDZd1", + "vertex": { + "schema-version": "v11", + "type": "pserver", + "key": "a5u3uo-4qpkw0-ba51-4jChYTSaDZd1", + "properties": { + "ptnii-equip-name": "fdsa", + "hostname": "mtanjasdf119snd", + "equip-type": "server-new", + "equip-vendor": "HP", + "equip-model": "DL380p-nd", + "in-maint": false, + "fqdn": "mtanjrsv119.mtanj.sbcglobal.net", + "purpose": "", + "ipv4-oam-address": "135.182.138.60", + "aai-node-type": "pserver" + } + }, + "operation": "UPDATE", + "timestamp": 1519189272444 + } + ], + "event-header": { + "timestamp": "1519189272555", + "id": "3b45dfa2-7a0a-47be-9b62-4jChYTSaDZd1", + "source-name": "SPIKE", + "entity-type": "pserver", + "event-type": "EMPTY-RULESET-EVENT" + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-bad-ipv4.json b/src/integration-test/resources/system_test/data/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-bad-ipv4.json new file mode 100644 index 0000000..dd9aa8c --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-bad-ipv4.json @@ -0,0 +1,225 @@ +{ + "cambria.partition": "AAI", + "entity": { + "equipment-role": "SESSION DIRECTR", + "resource-version": "1476738499", + "is-closed-loop-disabled": false, + "vnf-name": "ibcx0003v", + "vnf-type": "vUSP - Metaswitch vSBC", + "vnf-id": "ibcx0003v", + "in-maint": false, + "lag-interfaces": {}, + "l-interfaces": {}, + "prov-status": "NVTPROV", + "orchestration-status": "NOT ORCHESTRATED", + "ipv4-oam-address": "www.somecompany.com", + "service-id": "e433710f-9217-458d-a79d-1c7aff376d89", + "vf-modules": { + "vf-module": [{ + "resource-version": "1474037069", + "orchestration-status": "NOT ORCHESTRATED", + "heat-stack-id": "", + "is-base-vf-module": true, + "vf-module-id": "ibcx0003v", + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "227be8ce-05f9-4394-80c1-2f8f9f193a56" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm006", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/227be8ce-05f9-4394-80c1-2f8f9f193a56/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "30eb2f09-b029-477d-bdf3-a5159c51cc11" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm002", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/30eb2f09-b029-477d-bdf3-a5159c51cc11/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "782e344f-a77e-4c0f-970e-6d020cd694ed" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm001", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/782e344f-a77e-4c0f-970e-6d020cd694ed/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "4882b603-f769-4be8-99b1-c38b581d86fe" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm005", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/4882b603-f769-4be8-99b1-c38b581d86fe/", + "related-to": "vserver" + }] + }, + "vf-module-name": "ibcx0003v_migrated.base.module-0" + }] + }, + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "227be8ce-05f9-4394-80c1-2f8f9f193a56" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm006", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/227be8ce-05f9-4394-80c1-2f8f9f193a56/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "30eb2f09-b029-477d-bdf3-a5159c51cc11" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm002", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/30eb2f09-b029-477d-bdf3-a5159c51cc11/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "service-instance.service-instance-id", + "relationship-value": "62eb3798-b90d-4bc0-9635-c70473a49ae3" + }, { + "relationship-key": "service-subscription.service-type", + "relationship-value": "VIRTUAL USP" + }, { + "relationship-key": "customer.global-customer-id", + "relationship-value": "e433710f-9217-458d-a79d-1c7aff376d89" + }], + "related-to-property": [{ + "property-value": "", + "property-key": "service-instance.service-instance-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/business/customers/customer/e433710f-9217-458d-a79d-1c7aff376d89/service-subscriptions/service-subscription/VIRTUAL%20USP/service-instances/service-instance/62eb3798-b90d-4bc0-9635-c70473a49ae3/", + "related-to": "service-instance" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "782e344f-a77e-4c0f-970e-6d020cd694ed" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm001", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/782e344f-a77e-4c0f-970e-6d020cd694ed/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "4882b603-f769-4be8-99b1-c38b581d86fe" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm005", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/4882b603-f769-4be8-99b1-c38b581d86fe/", + "related-to": "vserver" + }] + } + }, + "event-header": { + "timestamp": "20161017-21:07:19:177", + "id": "20161017210719-5d536162-3a71-4daa-9059-ea45d6843584", + "action": "UPDATE", + "domain": "devINT1", + "source-name": "APPC", + "entity-link": "https://aai-app-e2e.test.att.com:8443/aai/v8/network/generic-vnfs/generic-vnf/ibcx0003v/", + "entity-type": "generic-vnf", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "generic-vnf", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-good-ipv4.json b/src/integration-test/resources/system_test/data/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-good-ipv4.json new file mode 100644 index 0000000..6eac627 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-good-ipv4.json @@ -0,0 +1,225 @@ +{ + "cambria.partition": "AAI", + "entity": { + "equipment-role": "SESSION DIRECTR", + "resource-version": "1476738999", + "is-closed-loop-disabled": false, + "vnf-name": "ibcx0003v", + "vnf-type": "vUSP - Metaswitch vSBC", + "vnf-id": "ibcx0003v", + "in-maint": false, + "lag-interfaces": {}, + "l-interfaces": {}, + "prov-status": "NVTPROV", + "orchestration-status": "NOT ORCHESTRATED", + "ipv4-oam-address": "192.168.2.1", + "service-id": "e433710f-9217-458d-a79d-1c7aff376d89", + "vf-modules": { + "vf-module": [{ + "resource-version": "1474037069", + "orchestration-status": "NOT ORCHESTRATED", + "heat-stack-id": "", + "is-base-vf-module": true, + "vf-module-id": "ibcx0003v", + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "227be8ce-05f9-4394-80c1-2f8f9f193a56" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm006", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/227be8ce-05f9-4394-80c1-2f8f9f193a56/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "30eb2f09-b029-477d-bdf3-a5159c51cc11" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm002", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/30eb2f09-b029-477d-bdf3-a5159c51cc11/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "782e344f-a77e-4c0f-970e-6d020cd694ed" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm001", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/782e344f-a77e-4c0f-970e-6d020cd694ed/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "4882b603-f769-4be8-99b1-c38b581d86fe" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm005", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/4882b603-f769-4be8-99b1-c38b581d86fe/", + "related-to": "vserver" + }] + }, + "vf-module-name": "ibcx0003v_migrated.base.module-0" + }] + }, + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "227be8ce-05f9-4394-80c1-2f8f9f193a56" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm006", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/227be8ce-05f9-4394-80c1-2f8f9f193a56/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "30eb2f09-b029-477d-bdf3-a5159c51cc11" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm002", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/30eb2f09-b029-477d-bdf3-a5159c51cc11/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "service-instance.service-instance-id", + "relationship-value": "62eb3798-b90d-4bc0-9635-c70473a49ae3" + }, { + "relationship-key": "service-subscription.service-type", + "relationship-value": "VIRTUAL USP" + }, { + "relationship-key": "customer.global-customer-id", + "relationship-value": "e433710f-9217-458d-a79d-1c7aff376d89" + }], + "related-to-property": [{ + "property-value": "", + "property-key": "service-instance.service-instance-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/business/customers/customer/e433710f-9217-458d-a79d-1c7aff376d89/service-subscriptions/service-subscription/VIRTUAL%20USP/service-instances/service-instance/62eb3798-b90d-4bc0-9635-c70473a49ae3/", + "related-to": "service-instance" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "782e344f-a77e-4c0f-970e-6d020cd694ed" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm001", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/782e344f-a77e-4c0f-970e-6d020cd694ed/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "4882b603-f769-4be8-99b1-c38b581d86fe" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm005", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/4882b603-f769-4be8-99b1-c38b581d86fe/", + "related-to": "vserver" + }] + } + }, + "event-header": { + "timestamp": "20161017-21:07:19:177", + "id": "20161017210719-5d536162-3a71-4daa-9059-ea45d6843584", + "action": "UPDATE", + "domain": "devINT1", + "source-name": "APPC", + "entity-link": "https://aai-app-e2e.test.att.com:8443/aai/v8/network/generic-vnfs/generic-vnf/ibcx0003v/", + "entity-type": "generic-vnf", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "generic-vnf", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-missing-ipv4.json b/src/integration-test/resources/system_test/data/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-missing-ipv4.json new file mode 100644 index 0000000..4d1ac13 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-missing-ipv4.json @@ -0,0 +1,224 @@ +{ + "cambria.partition": "AAI", + "entity": { + "equipment-role": "SESSION DIRECTR", + "resource-version": "1476738439", + "is-closed-loop-disabled": false, + "vnf-name": "ibcx0003v", + "vnf-type": "vUSP - Metaswitch vSBC", + "vnf-id": "ibcx0003v", + "in-maint": false, + "lag-interfaces": {}, + "l-interfaces": {}, + "prov-status": "NVTPROV", + "orchestration-status": "NOT ORCHESTRATED", + "service-id": "e433710f-9217-458d-a79d-1c7aff376d89", + "vf-modules": { + "vf-module": [{ + "resource-version": "1474037069", + "orchestration-status": "NOT ORCHESTRATED", + "heat-stack-id": "", + "is-base-vf-module": true, + "vf-module-id": "ibcx0003v", + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "227be8ce-05f9-4394-80c1-2f8f9f193a56" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm006", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/227be8ce-05f9-4394-80c1-2f8f9f193a56/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "30eb2f09-b029-477d-bdf3-a5159c51cc11" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm002", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/30eb2f09-b029-477d-bdf3-a5159c51cc11/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "782e344f-a77e-4c0f-970e-6d020cd694ed" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm001", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/782e344f-a77e-4c0f-970e-6d020cd694ed/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "4882b603-f769-4be8-99b1-c38b581d86fe" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm005", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/4882b603-f769-4be8-99b1-c38b581d86fe/", + "related-to": "vserver" + }] + }, + "vf-module-name": "ibcx0003v_migrated.base.module-0" + }] + }, + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "227be8ce-05f9-4394-80c1-2f8f9f193a56" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm006", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/227be8ce-05f9-4394-80c1-2f8f9f193a56/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "30eb2f09-b029-477d-bdf3-a5159c51cc11" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm002", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/30eb2f09-b029-477d-bdf3-a5159c51cc11/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "service-instance.service-instance-id", + "relationship-value": "62eb3798-b90d-4bc0-9635-c70473a49ae3" + }, { + "relationship-key": "service-subscription.service-type", + "relationship-value": "VIRTUAL USP" + }, { + "relationship-key": "customer.global-customer-id", + "relationship-value": "e433710f-9217-458d-a79d-1c7aff376d89" + }], + "related-to-property": [{ + "property-value": "", + "property-key": "service-instance.service-instance-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/business/customers/customer/e433710f-9217-458d-a79d-1c7aff376d89/service-subscriptions/service-subscription/VIRTUAL%20USP/service-instances/service-instance/62eb3798-b90d-4bc0-9635-c70473a49ae3/", + "related-to": "service-instance" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "782e344f-a77e-4c0f-970e-6d020cd694ed" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm001", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/782e344f-a77e-4c0f-970e-6d020cd694ed/", + "related-to": "vserver" + }, { + "relationship-data": [{ + "relationship-key": "vserver.vserver-id", + "relationship-value": "4882b603-f769-4be8-99b1-c38b581d86fe" + }, { + "relationship-key": "tenant.tenant-id", + "relationship-value": "092eb9e8e4b7412e8787dd091bc58e86" + }, { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }], + "related-to-property": [{ + "property-value": "ibcx0003vm005", + "property-key": "vserver.vserver-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86/vservers/vserver/4882b603-f769-4be8-99b1-c38b581d86fe/", + "related-to": "vserver" + }] + } + }, + "event-header": { + "timestamp": "20161017-21:07:19:177", + "id": "20161017210719-5d536162-3a71-4daa-9059-ea45d6843584", + "action": "UPDATE", + "domain": "devINT1", + "source-name": "APPC", + "entity-link": "https://aai-app-e2e.test.att.com:8443/aai/v8/network/generic-vnfs/generic-vnf/ibcx0003v/", + "entity-type": "generic-vnf", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "generic-vnf", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/gizmo/gizmo-pserver-create-event.json b/src/integration-test/resources/system_test/data/rule-driven/gizmo/gizmo-pserver-create-event.json new file mode 100644 index 0000000..d56d161 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/gizmo/gizmo-pserver-create-event.json @@ -0,0 +1,33 @@ +{ + "cambria.partition": "AAI", + "entity": { + "timestamp": 1514927928167, + "operation": "CREATE", + "vertex": { + "properties": { + "ipv4-oam-address": "1.2.3.4", + "resource-version": "1477013499", + "purpose": "my-purpose", + "fqdn": "myhost.onap.net", + "in-maint": false, + "equip-model": "DL380p-nd", + "equip-vendor": "HP", + "equip-type": "server", + "hostname": "myhost", + "ptnii-equip-name": "e-name" + }, + "key": "", + "type": "pserver", + "schema-version": "vX" + }, + "transaction-id": "c0a81fa7-5ef4-49cd-ab39-e42c53c9b9a4", + "database-transaction-id": "b3e2853e-f643-47a3-a0c3-cb54cc997ad3" + }, + "event-header": { + "timestamp": "1514927928167", + "id": "c0a81fa7-5ef4-49cd-ab39-e42c53c9b9a4", + "source-name": "GIZMO", + "entity-type": "pserver", + "event-type": "GIZMO-EVENT" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/newvce/newvce-INVALID-ACTION-AAI-EVENT-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/newvce/newvce-INVALID-ACTION-AAI-EVENT-devINT1.json new file mode 100644 index 0000000..7395d82 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/newvce/newvce-INVALID-ACTION-AAI-EVENT-devINT1.json @@ -0,0 +1,59 @@ +{ + "cambria.partition ": "AAI ", + "entity": { + "resource-version": "1476737775", + "equipment-role": "VCE", + "ipv4-oam-address": "10.40.128.162", + "prov-status": "NVTPROV", + "vnf-name2": "USETEEMTJWNVBR084", + "vnf-name": "mtjnj484vbc", + "vnf-type": "esx-vce", + "vnf-id2": "7150963a-9054-4046-a285-a572edf2deb6", + "l-interfaces": { + "l-interface": [{ + "resource-version": "1474030762", + "vlans": { + "vlan": [{ + "speed-value": "20", + "resource-version": "1474030762", + "speed-units": "Mbps", + "vlan-interface": "dp0p192p1.3087", + "vlan-id-inner": 3087, + "vlan-id-outer": 3503 + }] + }, + "v6-wan-link-ip": "2001:1890:1cff:ff01:0000:0000:ff00:0002", + "interface-name": "dp0p192p1", + "interface-role": "UPLINK" + }, { + "resource-version": "1474030762", + "vlans": { + "vlan": [{ + "speed-value": "20", + "resource-version": "1474030762", + "speed-units": "Mbps", + "vlan-interface": "dp0p224p1.2587", + "vlan-id-inner": 2587, + "vlan-id-outer": 3502 + }] + }, + "interface-name": "dp0p224p1", + "interface-role": "CUSTOMER" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:56:15:411", + "id": "20161017205615-c0e8aa29-dcf3-4267-9fd3-e508c2795e0a", + "action": "INVALID", + "domain": "devINT1", + "source-name": "NewvceCreator", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/network/newvces/newvce/7150963a-9054-4046-a285-a572edf2deb6", + "entity-type": "newvce", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "newvce", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/newvce/newvce-update-AAI-EVENT-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/newvce/newvce-update-AAI-EVENT-devINT1.json new file mode 100644 index 0000000..920ccea --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/newvce/newvce-update-AAI-EVENT-devINT1.json @@ -0,0 +1,59 @@ +{ + "cambria.partition ": "AAI ", + "entity": { + "resource-version": "1476737775", + "equipment-role": "VCE", + "ipv4-oam-address": "10.40.128.162", + "prov-status": "NVTPROV", + "vnf-name2": "USETEEMTJWNVBR084", + "vnf-name": "mtjnj484vbc", + "vnf-type": "esx-vce", + "vnf-id2": "7150963a-9054-4046-a285-a572edf2deb6", + "l-interfaces": { + "l-interface": [{ + "resource-version": "1474030762", + "vlans": { + "vlan": [{ + "speed-value": "20", + "resource-version": "1474030762", + "speed-units": "Mbps", + "vlan-interface": "dp0p192p1.3087", + "vlan-id-inner": 3087, + "vlan-id-outer": 3503 + }] + }, + "v6-wan-link-ip": "2001:1890:1cff:ff01:0000:0000:ff00:0002", + "interface-name": "dp0p192p1", + "interface-role": "UPLINK" + }, { + "resource-version": "1474030762", + "vlans": { + "vlan": [{ + "speed-value": "20", + "resource-version": "1474030762", + "speed-units": "Mbps", + "vlan-interface": "dp0p224p1.2587", + "vlan-id-inner": 2587, + "vlan-id-outer": 3502 + }] + }, + "interface-name": "dp0p224p1", + "interface-role": "CUSTOMER" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:56:15:411", + "id": "20161017205615-c0e8aa29-dcf3-4267-9fd3-e508c2795e0a", + "action": "UPDATE", + "domain": "devINT1", + "source-name": "NewvceCreator", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/network/newvces/newvce/7150963a-9054-4046-a285-a572edf2deb6", + "entity-type": "newvce", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "newvce", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-name.json b/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-name.json new file mode 100644 index 0000000..965c7f7 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-name.json @@ -0,0 +1,128 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v8", + "action": "CREATE", + "entity-type": "pserver", + "top-entity-type": "pserver", + "entity-link": "https://inventory/v8/cloud-infrastructure/pservers/pserver/example-vserver-id-val-34666" + }, + "entity": { + "hostname": "gdrmi101sd9", + "ptnii-equip-name": "gdrmi101sd9.infra.aic.att.net", + "equip-type": "server", + "equip-vendor": "HP", + "equip-model": "DL380p9-nd", + "fqdn": "gdrmirsv101.gdrmi.sbcglobal.net", + "ipv4-oam-address": "12.80.20.75", + "in-maint": false, + "resource-version": "1478050351", + "purpose": "LCP", + "inv-status": "In Service", + "relationship-list": { + "relationship": [ + { + "related-to": "complex", + "related-link": "https://inventory/v8/cloud-infrastructure/complexes/complex/GDRPMIBL/", + "relationship-data": [ + { + "relationship-key": "complex.physical-location-id", + "relationship-value": "GDRPMIBL" + } + ] + } + ] + }, + "p-interfaces": { + "p-interface": [ + { + "interface-name": "p4p1-4/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051189", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p1-4%2F1%7Cgdrmitax101%3Axe-0%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p1-4/1|gdrmitax101:xe-0/0/1" + } + ] + } + ] + } + }, + { + "interface-name": "p4p2-4/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051190", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p2-4%2F2%7Cgdrmitax101%3Axe-0%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p2-4/2|gdrmitax101:xe-0/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p1-6/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051200", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p1-6%2F1%7Cgdrmitax102%3Axe-1%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p1-6/1|gdrmitax102:xe-1/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p2-6/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051199", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p2-6%2F2%7Cgdrmitax102%3Axe-1%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p2-6/2|gdrmitax102:xe-1/0/1" + } + ] + } + ] + } + } + ] + } + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-type.json b/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-type.json new file mode 100644 index 0000000..6985008 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-type.json @@ -0,0 +1,128 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v8", + "action": "CREATE", + "entity-type": "pserver", + "top-entity-type": "pserver", + "entity-link": "https://inventory/v8/cloud-infrastructure/pservers/pserver/example-vserver-id-val-34666" + }, + "entity": { + "hostname": "gdrmi101sd9", + "ptnii-equip-name": "gdrmi101sd9", + "equip-type": "toa", + "equip-vendor": "HP", + "equip-model": "DL380p9-nd", + "fqdn": "gdrmirsv101.gdrmi.sbcglobal.net", + "ipv4-oam-address": "12.80.20.75", + "in-maint": false, + "resource-version": "1478050351", + "purpose": "LCP", + "inv-status": "In Service", + "relationship-list": { + "relationship": [ + { + "related-to": "complex", + "related-link": "https://inventory/v8/cloud-infrastructure/complexes/complex/GDRPMIBL/", + "relationship-data": [ + { + "relationship-key": "complex.physical-location-id", + "relationship-value": "GDRPMIBL" + } + ] + } + ] + }, + "p-interfaces": { + "p-interface": [ + { + "interface-name": "p4p1-4/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051189", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p1-4%2F1%7Cgdrmitax101%3Axe-0%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p1-4/1|gdrmitax101:xe-0/0/1" + } + ] + } + ] + } + }, + { + "interface-name": "p4p2-4/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051190", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p2-4%2F2%7Cgdrmitax101%3Axe-0%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p2-4/2|gdrmitax101:xe-0/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p1-6/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051200", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p1-6%2F1%7Cgdrmitax102%3Axe-1%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p1-6/1|gdrmitax102:xe-1/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p2-6/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051199", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p2-6%2F2%7Cgdrmitax102%3Axe-1%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p2-6/2|gdrmitax102:xe-1/0/1" + } + ] + } + ] + } + } + ] + } + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-good.json b/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-good.json new file mode 100644 index 0000000..889cdde --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-good.json @@ -0,0 +1,128 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v8", + "action": "CREATE", + "entity-type": "pserver", + "top-entity-type": "pserver", + "entity-link": "https://inventory/v8/cloud-infrastructure/pservers/pserver/example-vserver-id-val-34666" + }, + "entity": { + "hostname": "gdrmi101sd9", + "ptnii-equip-name": "gdrmi101sd9", + "equip-type": "server", + "equip-vendor": "HP", + "equip-model": "DL380p9-nd", + "fqdn": "gdrmirsv101.gdrmi.sbcglobal.net", + "ipv4-oam-address": "12.80.20.75", + "in-maint": false, + "resource-version": "1478050351", + "purpose": "LCP", + "inv-status": "In Service", + "relationship-list": { + "relationship": [ + { + "related-to": "complex", + "related-link": "https://inventory/v8/cloud-infrastructure/complexes/complex/GDRPMIBL/", + "relationship-data": [ + { + "relationship-key": "complex.physical-location-id", + "relationship-value": "GDRPMIBL" + } + ] + } + ] + }, + "p-interfaces": { + "p-interface": [ + { + "interface-name": "p4p1-4/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051189", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p1-4%2F1%7Cgdrmitax101%3Axe-0%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p1-4/1|gdrmitax101:xe-0/0/1" + } + ] + } + ] + } + }, + { + "interface-name": "p4p2-4/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051190", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p2-4%2F2%7Cgdrmitax101%3Axe-0%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p2-4/2|gdrmitax101:xe-0/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p1-6/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051200", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p1-6%2F1%7Cgdrmitax102%3Axe-1%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p1-6/1|gdrmitax102:xe-1/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p2-6/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051199", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p2-6%2F2%7Cgdrmitax102%3Axe-1%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p2-6/2|gdrmitax102:xe-1/0/1" + } + ] + } + ] + } + } + ] + } + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status-missing.json b/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status-missing.json new file mode 100644 index 0000000..af0c5b7 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status-missing.json @@ -0,0 +1,127 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v8", + "action": "CREATE", + "entity-type": "pserver", + "top-entity-type": "pserver", + "entity-link": "https://inventory/v8/cloud-infrastructure/pservers/pserver/example-vserver-id-val-34666" + }, + "entity": { + "hostname": "gdrmi101sd9", + "ptnii-equip-name": "gdrmi101sd9", + "equip-type": "server", + "equip-vendor": "HP", + "equip-model": "DL380p9-nd", + "fqdn": "gdrmirsv101.gdrmi.sbcglobal.net", + "ipv4-oam-address": "12.80.20.75", + "in-maint": false, + "resource-version": "1478050351", + "purpose": "LCP", + "relationship-list": { + "relationship": [ + { + "related-to": "complex", + "related-link": "https://inventory/v8/cloud-infrastructure/complexes/complex/GDRPMIBL/", + "relationship-data": [ + { + "relationship-key": "complex.physical-location-id", + "relationship-value": "GDRPMIBL" + } + ] + } + ] + }, + "p-interfaces": { + "p-interface": [ + { + "interface-name": "p4p1-4/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051189", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p1-4%2F1%7Cgdrmitax101%3Axe-0%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p1-4/1|gdrmitax101:xe-0/0/1" + } + ] + } + ] + } + }, + { + "interface-name": "p4p2-4/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051190", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p2-4%2F2%7Cgdrmitax101%3Axe-0%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p2-4/2|gdrmitax101:xe-0/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p1-6/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051200", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p1-6%2F1%7Cgdrmitax102%3Axe-1%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p1-6/1|gdrmitax102:xe-1/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p2-6/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051199", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p2-6%2F2%7Cgdrmitax102%3Axe-1%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p2-6/2|gdrmitax102:xe-1/0/1" + } + ] + } + ] + } + } + ] + } + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status.json b/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status.json new file mode 100644 index 0000000..fb5d4f4 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status.json @@ -0,0 +1,128 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v8", + "action": "CREATE", + "entity-type": "pserver", + "top-entity-type": "pserver", + "entity-link": "https://inventory/v8/cloud-infrastructure/pservers/pserver/example-vserver-id-val-34666" + }, + "entity": { + "hostname": "gdrmi101sd9", + "ptnii-equip-name": "gdrmi101sd9", + "equip-type": "server", + "equip-vendor": "HP", + "equip-model": "DL380p9-nd", + "fqdn": "gdrmirsv101.gdrmi.sbcglobal.net", + "ipv4-oam-address": "12.80.20.75", + "in-maint": false, + "resource-version": "1478050351", + "purpose": "LCP", + "inv-status": "Incorrect status value", + "relationship-list": { + "relationship": [ + { + "related-to": "complex", + "related-link": "https://inventory/v8/cloud-infrastructure/complexes/complex/GDRPMIBL/", + "relationship-data": [ + { + "relationship-key": "complex.physical-location-id", + "relationship-value": "GDRPMIBL" + } + ] + } + ] + }, + "p-interfaces": { + "p-interface": [ + { + "interface-name": "p4p1-4/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051189", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p1-4%2F1%7Cgdrmitax101%3Axe-0%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p1-4/1|gdrmitax101:xe-0/0/1" + } + ] + } + ] + } + }, + { + "interface-name": "p4p2-4/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051190", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p2-4%2F2%7Cgdrmitax101%3Axe-0%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p2-4/2|gdrmitax101:xe-0/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p1-6/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051200", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p1-6%2F1%7Cgdrmitax102%3Axe-1%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p1-6/1|gdrmitax102:xe-1/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p2-6/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051199", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p2-6%2F2%7Cgdrmitax102%3Axe-1%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p2-6/2|gdrmitax102:xe-1/0/1" + } + ] + } + ] + } + } + ] + } + } +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/data/rule-driven/vf-module/vf-module-delete-AAI-EVENT-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/vf-module/vf-module-delete-AAI-EVENT-devINT1.json new file mode 100644 index 0000000..84e6f0f --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vf-module/vf-module-delete-AAI-EVENT-devINT1.json @@ -0,0 +1,45 @@ +{ + "cambria.partition": "AAI", + "entity": { + "vnf-id": "baa824f4-57a9-4d7b-a5fa-cbc42b0860d3", + "vf-modules": { + "vf-module": [{ + "persona-model-version": "1", + "persona-model-id": "199bb5d6-2104-47f3-ad03-8684e55f7061", + "resource-version": "1476735608", + "orchestration-status": "pending-delete", + "is-base-vf-module": true, + "vf-module-id": "da7b73c7-f9ab-4ca4-8c56-bd220329afb2", + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "l3-network.network-id", + "relationship-value": "6bf31bb1-1ec4-423f-a03f-5b81b4410606" + }], + "related-to-property": [{ + "property-value": "Trinity_OAMP_3900", + "property-key": "l3-network.network-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/network/l3-networks/l3-network/6bf31bb1-1ec4-423f-a03f-5b81b4410606/", + "related-to": "l3-network" + }] + }, + "vf-module-name": "fnfm0001v_base_module" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:20:10:357", + "id": "20161017202010-54bef76b-32b9-442b-bca8-b31f1cc84a84", + "action": "DELETE", + "domain": "devINT1", + "source-name": "MSO", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/network/generic-vnfs/generic-vnf/baa824f4-57a9-4d7b-a5fa-cbc42b0860d3/vf-modules/vf-module/da7b73c7-f9ab-4ca4-8c56-bd220329afb2/", + "entity-type": "vf-module", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "generic-vnf", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vf-module/vf-module-delete-AAI-EVENT-e2e1.json b/src/integration-test/resources/system_test/data/rule-driven/vf-module/vf-module-delete-AAI-EVENT-e2e1.json new file mode 100644 index 0000000..5213894 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vf-module/vf-module-delete-AAI-EVENT-e2e1.json @@ -0,0 +1,45 @@ +{ + "cambria.partition": "AAI", + "entity": { + "vnf-id": "baa824f4-57a9-4d7b-a5fa-cbc42b0860d3", + "vf-modules": { + "vf-module": [{ + "persona-model-version": "1", + "persona-model-id": "199bb5d6-2104-47f3-ad03-8684e55f7061", + "resource-version": "1476735608", + "orchestration-status": "pending-delete", + "is-base-vf-module": true, + "vf-module-id": "da7b73c7-f9ab-4ca4-8c56-bd220329afb2", + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "l3-network.network-id", + "relationship-value": "6bf31bb1-1ec4-423f-a03f-5b81b4410606" + }], + "related-to-property": [{ + "property-value": "Trinity_OAMP_3900", + "property-key": "l3-network.network-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/network/l3-networks/l3-network/6bf31bb1-1ec4-423f-a03f-5b81b4410606/", + "related-to": "l3-network" + }] + }, + "vf-module-name": "fnfm0001v_base_module" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:20:10:357", + "id": "20161017202010-54bef76b-32b9-442b-bca8-b31f1cc84a84", + "action": "DELETE", + "domain": "e2e1", + "source-name": "MSO", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/network/generic-vnfs/generic-vnf/baa824f4-57a9-4d7b-a5fa-cbc42b0860d3/vf-modules/vf-module/da7b73c7-f9ab-4ca4-8c56-bd220329afb2/", + "entity-type": "vf-module", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "generic-vnf", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vf-module/vf-module-delete-AAI-RUBBISH-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/vf-module/vf-module-delete-AAI-RUBBISH-devINT1.json new file mode 100644 index 0000000..b89b236 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vf-module/vf-module-delete-AAI-RUBBISH-devINT1.json @@ -0,0 +1,45 @@ +{ + "cambria.partition": "AAI", + "entity": { + "vnf-id": "baa824f4-57a9-4d7b-a5fa-cbc42b0860d3", + "vf-modules": { + "vf-module": [{ + "persona-model-version": "1", + "persona-model-id": "199bb5d6-2104-47f3-ad03-8684e55f7061", + "resource-version": "1476735608", + "orchestration-status": "pending-delete", + "is-base-vf-module": true, + "vf-module-id": "da7b73c7-f9ab-4ca4-8c56-bd220329afb2", + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "l3-network.network-id", + "relationship-value": "6bf31bb1-1ec4-423f-a03f-5b81b4410606" + }], + "related-to-property": [{ + "property-value": "Trinity_OAMP_3900", + "property-key": "l3-network.network-name" + }], + "related-link": "https://aai-app-e2e.ecomp.cci.att.com:8443/aai/v8/network/l3-networks/l3-network/6bf31bb1-1ec4-423f-a03f-5b81b4410606/", + "related-to": "l3-network" + }] + }, + "vf-module-name": "fnfm0001v_base_module" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:20:10:357", + "id": "20161017202010-54bef76b-32b9-442b-bca8-b31f1cc84a84", + "action": "DELETE", + "domain": "devINT1", + "source-name": "MSO", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/network/generic-vnfs/generic-vnf/baa824f4-57a9-4d7b-a5fa-cbc42b0860d3/vf-modules/vf-module/da7b73c7-f9ab-4ca4-8c56-bd220329afb2/", + "entity-type": "vf-module", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-RUBBISH", + "top-entity-type": "generic-vnf", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vnf-image/vnf-image-create-AAI-EVENT-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/vnf-image/vnf-image-create-AAI-EVENT-devINT1.json new file mode 100644 index 0000000..63da74b --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vnf-image/vnf-image-create-AAI-EVENT-devINT1.json @@ -0,0 +1,24 @@ +{ + "cambria.partition": "AAI", + "entity": { + "resource-version": "1476735375", + "application": "VM01", + "att-uuid": "750c29ff-12cb-4be5-88bc-648f27748113", + "application-vendor": "FORTINET", + "application-version": "5.2.7" + }, + "event-header": { + "timestamp": "20161017-20:16:15:401", + "id": "20161017201615-5c32427c-1354-4c40-924d-ef860580287e", + "action": "CREATE", + "domain": "devINT1", + "source-name": "ModelLoader", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/service-design-and-creation/vnf-images/vnf-image/750c29ff-12cb-4be5-88bc-648f27748113", + "entity-type": "vnf-image", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "vnf-image", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-BAD.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-BAD.json new file mode 100644 index 0000000..ad459ee --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-BAD.json @@ -0,0 +1,144 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v7", + "action": "CREATE", + "entity-type": "vserver", + "top-entity-type": "cloud-region", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666" + }, + "entity": { + "cloud-owner": "att-aic", + "cloud-region-id": "AAIAIC25", + "tenants": { + "tenant": [{ + "tenant-id": "example-tenant-id-val-88551", + "tenant-name": "example-tenant-name-val-88551", + "vservers": { + "vserver": [{ + "vserver-id": "c385bb3e-6ebd-4898-bc92-792e0ac2db50", + "vserver-name": "bems0001vm001", + "vserver-name2": "bems0001vm001bem001-1452", + "prov-status": "ACTIVE", + "vserver-selflink": "TRINITY vserverLink", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1475160142", + "relationship-list": { + "relationship": [{ + "related-to": "generic-vnf", + "related-link": "https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx12345v/", + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "ctpx12345v" + }], + "related-to-property": [{ + "property-key": "generic-vnf.vnf-name", + "property-value": "ctpx12345v" + }] + }, + { + "related-to": "vf-module", + "related-link": "https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx12345v/vf-modules/vf-module/ctpx12345v/", + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "ctpx12345v" + }, + { + "relationship-key": "vf-module.vf-module-id", + "relationship-value": "ctpx12345v" + }] + }, + { + "related-to": "image", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/images/image/TRINITY-IMAGE/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "image.image-id", + "relationship-value": "TRINITY-IMAGE" + }], + "related-to-property": [{ + "property-key": "image.image-name", + "property-value": "TRINITY IMAGE" + }] + }, + { + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/TRINITY-PSERVER/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "TRINITY-PSERVER" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, + { + "related-to": "flavor", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/flavors/flavor/TRINITY-Flavor/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "flavor.flavor-id", + "relationship-value": "TRINITY-Flavor" + }], + "related-to-property": [{ + "property-key": "flavor.flavor-name", + "property-value": "TRINITY Flavor" + }] + }] + }, + "l-interfaces": { + "l-interface": [{ + "interface-name": "BSFT-EMS-VMVNIC1", + "resource-version": "1455590484", + "l3-interface-ipv4-address-list": [{ + "l3-interface-ipv4-address": "130.3.148.14", + "l3-interface-ipv4-prefix-length": 32, + "resource-version": "1455590484", + "relationship-list": { + "relationship": [{ + "related-to": "subnet", + "related-link": "https://135.16.121.249:8443/aai/v8/network/l3-networks/l3-network/AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1/subnets/subnet/AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1-ipv4/", + "relationship-data": [{ + "relationship-key": "l3-network.network-id", + "relationship-value": "AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1" + }, + { + "relationship-key": "subnet.subnet-id", + "relationship-value": "AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1-ipv4" + }], + "related-to-property": [{ + "property-key": "subnet.subnet-name" + }] + }] + } + }] + }] + } + }] + } + }] + } + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-GOOD.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-GOOD.json new file mode 100644 index 0000000..55b5a6c --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-GOOD.json @@ -0,0 +1,144 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v7", + "action": "CREATE", + "entity-type": "vserver", + "top-entity-type": "cloud-region", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666" + }, + "entity": { + "cloud-owner": "att-aic", + "cloud-region-id": "AAIAIC25", + "tenants": { + "tenant": [{ + "tenant-id": "example-tenant-id-val-88551", + "tenant-name": "example-tenant-name-val-88551", + "vservers": { + "vserver": [{ + "vserver-id": "c385bb3e-6ebd-4898-bc92-792e0ac2db50", + "vserver-name": "bems0001vm001", + "vserver-name2": "bems0001vm001bem001-1452", + "prov-status": "ACTIVE", + "vserver-selflink": "TRINITY vserverLink", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1475160142", + "relationship-list": { + "relationship": [{ + "related-to": "generic-vnf", + "related-link": "https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx0001v/", + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "ctpx0001v" + }], + "related-to-property": [{ + "property-key": "generic-vnf.vnf-name", + "property-value": "ctpx0001v" + }] + }, + { + "related-to": "vf-module", + "related-link": "https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx0001v/vf-modules/vf-module/ctpx0001v/", + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "ctpx0001v" + }, + { + "relationship-key": "vf-module.vf-module-id", + "relationship-value": "ctpx0001v" + }] + }, + { + "related-to": "image", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/images/image/TRINITY-IMAGE/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "image.image-id", + "relationship-value": "TRINITY-IMAGE" + }], + "related-to-property": [{ + "property-key": "image.image-name", + "property-value": "TRINITY IMAGE" + }] + }, + { + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/TRINITY-PSERVER/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "TRINITY-PSERVER" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, + { + "related-to": "flavor", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/flavors/flavor/TRINITY-Flavor/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "flavor.flavor-id", + "relationship-value": "TRINITY-Flavor" + }], + "related-to-property": [{ + "property-key": "flavor.flavor-name", + "property-value": "TRINITY Flavor" + }] + }] + }, + "l-interfaces": { + "l-interface": [{ + "interface-name": "BSFT-EMS-VMVNIC1", + "resource-version": "1455590484", + "l3-interface-ipv4-address-list": [{ + "l3-interface-ipv4-address": "130.3.148.14", + "l3-interface-ipv4-prefix-length": 32, + "resource-version": "1455590484", + "relationship-list": { + "relationship": [{ + "related-to": "subnet", + "related-link": "https://135.16.121.249:8443/aai/v8/network/l3-networks/l3-network/AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1/subnets/subnet/AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1-ipv4/", + "relationship-data": [{ + "relationship-key": "l3-network.network-id", + "relationship-value": "AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1" + }, + { + "relationship-key": "subnet.subnet-id", + "relationship-value": "AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1-ipv4" + }], + "related-to-property": [{ + "property-key": "subnet.subnet-name" + }] + }] + } + }] + }] + } + }] + } + }] + } + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-malformed-JSON.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-malformed-JSON.json new file mode 100644 index 0000000..7eae30a --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-malformed-JSON.json @@ -0,0 +1,158 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v7", + "action": "CREATE", + "entity-type": "vserver", + "top-entity-type": "cloud-region", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666" + }, + "entity": { + "cloud-owner": "att-aic", + "cloud-region-id": "AAIAIC25", + "tenants": { + "tenant": [{ + "tenant-id": "example-tenant-id-val-88551", + "tenant-name": "example-tenant-name-val-88551", + "vservers": { + "vserver": [{ + "vserver-id": "c385bb3e-6ebd-4898-bc92-792e0ac2db50", + "vserver-name": "bems0001vm001", + "vserver-name2": "bems0001vm001bem001-1452", + "prov-status": "ACTIVE", + "vserver-selflink": "TRINITY vserverLink", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1475160142", + "relationship-list": { + "relationship": [{ + "related-to": "generic-vnf", + "related-link": "https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx0001v/", + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "ctpx0001v" + }], + "related-to-property": [{ + "property-key": "generic-vnf.vnf-name", + "property-value": "ctpx0001v" + }] + }, + { + "related-to": "vf-module", + "related-link": "https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx0001v/vf-modules/vf-module/ctpx0001v/", + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "ctpx0001v" + }, + { + "relationship-key": "vf-module.vf-module-id", + "relationship-value": "ctpx0001v" + }] + }, + { + "related-to": "image", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/images/image/TRINITY-IMAGE/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "image.image-id", + "relationship-value": "TRINITY-IMAGE" + }], + "related-to-property": [{ + "property-key": "image.image-name", + "property-value": "TRINITY IMAGE" + }] + }, + { + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/TRINITY-PSERVER/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "TRINITY-PSERVER" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, + { + "related-to": "flavor", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/flavors/flavor/TRINITY-Flavor/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "flavor.flavor-id", + "relationship-value": "TRINITY-Flavor" + }], + "related-to-property": [{ + "property-key": "flavor.flavor-name", + "property-value": "TRINITY Flavor" + }] + }] + }, + "l-interfaces": { + "l-interface": [{ + "interface-name": "BSFT-EMS-VMVNIC1", + "resource-version": "1455590484", + "l3-interface-ipv4-address-list": [{ + "l3-interface-ipv4-address": "130.3.148.14", + "l3-interface-ipv4-prefix-length": 32, + "resource-version": "1455590484", + "relationship-list": { + "relationship": [{ + "related-to": "subnet", + "related-link": "https://135.16.121.249:8443/aai/v8/network/l3-networks/l3-network/AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1/subnets/subnet/AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1-ipv4/", + "relationship-data": [{ + "relationship-key": "l3-network.network-id", + "relationship-value": "AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1" + }, + { + "relationship-key": "subnet.subnet-id", + "relationship-value": "AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1-ipv4" + }], + "related-to-property": [{ + "property-key": "subnet.subnet-name" + }] + }] + } + }] + }] + } + }], + "l3-interface-ipv6-address-list": [{ + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-88071", + "l3-interface-ipv6-prefix-length": 55080281, + "vlan-id-inner": 55080281, + "vlan-id-outer": 55080281, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + }] + }] + } + }] + } +}] +} +} +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-two-vserver-objects.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-two-vserver-objects.json new file mode 100644 index 0000000..8879ffe --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-two-vserver-objects.json @@ -0,0 +1,259 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v7", + "action": "CREATE", + "entity-type": "vserver", + "top-entity-type": "cloud-region", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666" + }, + "entity": { + "cloud-owner": "att-aic", + "cloud-region-id": "AAIAIC25", + "tenants": { + "tenant": [{ + "tenant-id": "example-tenant-id-val-88551", + "tenant-name": "example-tenant-name-val-88551", + "vservers": { + "vserver": [{ + "vserver-id": "c385bb3e-6ebd-4898-bc92-792e0ac2db50", + "vserver-name": "bems0001vm001", + "vserver-name2": "bems0001vm001bem001-1452", + "prov-status": "ACTIVE", + "vserver-selflink": "TRINITY vserverLink", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1475160142", + "relationship-list": { + "relationship": [{ + "related-to": "generic-vnf", + "related-link": "https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx0002v/", + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "ctpx0002v" + }], + "related-to-property": [{ + "property-key": "generic-vnf.vnf-name", + "property-value": "ctpx0002v" + }] + }, + { + "related-to": "vf-module", + "related-link": "https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx0001v/vf-modules/vf-module/ctpx0001v/", + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "ctpx0001v" + }, + { + "relationship-key": "vf-module.vf-module-id", + "relationship-value": "ctpx0001v" + }] + }, + { + "related-to": "image", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/images/image/TRINITY-IMAGE/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "image.image-id", + "relationship-value": "TRINITY-IMAGE" + }], + "related-to-property": [{ + "property-key": "image.image-name", + "property-value": "TRINITY IMAGE" + }] + }, + { + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/TRINITY-PSERVER/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "TRINITY-PSERVER" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, + { + "related-to": "flavor", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/flavors/flavor/TRINITY-Flavor/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "flavor.flavor-id", + "relationship-value": "TRINITY-Flavor" + }], + "related-to-property": [{ + "property-key": "flavor.flavor-name", + "property-value": "TRINITY Flavor" + }] + }] + }, + "l-interfaces": { + "l-interface": [{ + "interface-name": "BSFT-EMS-VMVNIC1", + "resource-version": "1455590484", + "l3-interface-ipv4-address-list": [{ + "l3-interface-ipv4-address": "130.3.148.14", + "l3-interface-ipv4-prefix-length": 32, + "resource-version": "1455590484", + "relationship-list": { + "relationship": [{ + "related-to": "subnet", + "related-link": "https://135.16.121.249:8443/aai/v8/network/l3-networks/l3-network/AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1/subnets/subnet/AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1-ipv4/", + "relationship-data": [{ + "relationship-key": "l3-network.network-id", + "relationship-value": "AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1" + }, + { + "relationship-key": "subnet.subnet-id", + "relationship-value": "AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1-ipv4" + }], + "related-to-property": [{ + "property-key": "subnet.subnet-name" + }] + }] + } + }] + }] + } + }, + { + "vserver-id": "c385bb3e-6ebd-4898-bc92-792e0ac2db51", + "vserver-name": "bems0001vm002", + "vserver-name2": "bems0001vm002bem001-1452", + "prov-status": "ACTIVE", + "vserver-selflink": "TRINITY vserverLink", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1475160143", + "relationship-list": { + "relationship": [{ + "related-to": "generic-vnf", + "related-link": "https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx0002v/", + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "ctpx0002v" + }], + "related-to-property": [{ + "property-key": "generic-vnf.vnf-name", + "property-value": "ctpx0002v" + }] + }, + { + "related-to": "vf-module", + "related-link": "https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx0002v/vf-modules/vf-module/ctpx0002v/", + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "ctpx0002v" + }, + { + "relationship-key": "vf-module.vf-module-id", + "relationship-value": "ctpx0002v" + }] + }, + { + "related-to": "image", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/images/image/TRINITY-IMAGE/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "image.image-id", + "relationship-value": "TRINITY-IMAGE" + }], + "related-to-property": [{ + "property-key": "image.image-name", + "property-value": "TRINITY IMAGE" + }] + }, + { + "related-to": "pserver", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/TRINITY-PSERVER/", + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "TRINITY-PSERVER" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }] + }, + { + "related-to": "flavor", + "related-link": "https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/flavors/flavor/TRINITY-Flavor/", + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "flavor.flavor-id", + "relationship-value": "TRINITY-Flavor" + }], + "related-to-property": [{ + "property-key": "flavor.flavor-name", + "property-value": "TRINITY Flavor" + }] + }] + }, + "l-interfaces": { + "l-interface": [{ + "interface-name": "BSFT-EMS-VMVNIC1", + "resource-version": "1455590484", + "l3-interface-ipv4-address-list": [{ + "l3-interface-ipv4-address": "130.3.148.14", + "l3-interface-ipv4-prefix-length": 32, + "resource-version": "1455590484", + "relationship-list": { + "relationship": [{ + "related-to": "subnet", + "related-link": "https://135.16.121.249:8443/aai/v8/network/l3-networks/l3-network/AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1/subnets/subnet/AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1-ipv4/", + "relationship-data": [{ + "relationship-key": "l3-network.network-id", + "relationship-value": "AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1" + }, + { + "relationship-key": "subnet.subnet-id", + "relationship-value": "AIC_SBG_NSDNet_Trinity_OAMP_3900-1234-1-ipv4" + }], + "related-to-property": [{ + "property-key": "subnet.subnet-name" + }] + }] + } + }] + }] + } + }] + } + }] + } + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1.json new file mode 100644 index 0000000..b77fd8a --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1.json @@ -0,0 +1,164 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v7", + "action": "CREATE", + "entity-type": "vserver", + "top-entity-type": "cloud-region", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666" + }, + "entity": { + "cloud-owner": "att-aic", + "cloud-region-id": "AAIAIC25", + "tenants": { + "tenant": [ + { + "tenant-id": "example-tenant-id-val-88551", + "tenant-name": "example-tenant-name-val-88551", + "vservers": { + "vserver": [ + { + "vserver-id": "example-vserver-id-val-34666", + "vserver-name": "example-vserver-name-val-34666", + "vserver-name2": "example-vserver-name2-val-34666", + "prov-status": "PREPROV", + "vserver-selflink": "example-vserver-selflink-val-34666", + "in-maint": true, + "is-closed-loop-disabled": true, + "resource-version": "1464193654", + "volumes": { + "volume": [ + { + "volume-id": "example-volume-id-val-79195", + "volume-selflink": "example-volume-selflink-val-79195", + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + }, + "relationship-list": { + + }, + "l-interfaces": { + "l-interface": [ + { + "interface-name": "example-interface-name-val-25679", + "interface-role": "example-interface-role-val-25679", + "v6-wan-link-ip": "example-v6-wan-link-ip-val-25679", + "selflink": "example-selflink-val-25679", + "interface-id": "example-interface-id-val-25679", + "macaddr": "example-macaddr-val-25679", + "network-name": "example-network-name-val-25679", + "resource-version": "1464193654", + "vlans": { + "vlan": [ + { + "vlan-interface": "example-vlan-interface-val-28675", + "vlan-id-inner": 22278797, + "vlan-id-outer": 22278797, + "resource-version": "1464193654", + "speed-value": "example-speed-value-val-28675", + "speed-units": "example-speed-units-val-28675", + "vlan-description": "example-vlan-description-val-28675", + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-39271", + "l3-interface-ipv4-prefix-length": 78868308, + "vlan-id-inner": 78868308, + "vlan-id-outer": 78868308, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-4005", + "l3-interface-ipv6-prefix-length": 78340763, + "vlan-id-inner": 78340763, + "vlan-id-outer": 78340763, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + } + ] + }, + "sriov-vfs": { + "sriov-vf": [ + { + "pci-id": "example-pci-id-val-85354", + "vf-vlan-filter": "example-vf-vlan-filter-val-85354", + "vf-mac-filter": "example-vf-mac-filter-val-85354", + "vf-vlan-strip": true, + "vf-vlan-anti-spoof-check": true, + "vf-mac-anti-spoof-check": true, + "vf-mirrors": "example-vf-mirrors-val-85354", + "vf-broadcast-allow": true, + "vf-unknown-multicast-allow": true, + "vf-unknown-unicast-allow": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + }, + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-21446", + "l3-interface-ipv4-prefix-length": 71127022, + "vlan-id-inner": 71127022, + "vlan-id-outer": 71127022, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-88071", + "l3-interface-ipv6-prefix-length": 55080281, + "vlan-id-inner": 55080281, + "vlan-id-outer": 55080281, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + } + ] + } + } + ] + } + } + ] + } + } +} + diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-e2e1.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-e2e1.json new file mode 100644 index 0000000..21d705c --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-EVENT-e2e1.json @@ -0,0 +1,164 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "e2e1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "version": "v7", + "action": "CREATE", + "entity-type": "vserver", + "top-entity-type": "cloud-region", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666" + }, + "entity": { + "cloud-owner": "att-aic", + "cloud-region-id": "AAIAIC25", + "tenants": { + "tenant": [ + { + "tenant-id": "example-tenant-id-val-88551", + "tenant-name": "example-tenant-name-val-88551", + "vservers": { + "vserver": [ + { + "vserver-id": "example-vserver-id-val-34666", + "vserver-name": "example-vserver-name-val-34666", + "vserver-name2": "example-vserver-name2-val-34666", + "prov-status": "PREPROV", + "vserver-selflink": "example-vserver-selflink-val-34666", + "in-maint": true, + "is-closed-loop-disabled": true, + "resource-version": "1464193654", + "volumes": { + "volume": [ + { + "volume-id": "example-volume-id-val-79195", + "volume-selflink": "example-volume-selflink-val-79195", + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + }, + "relationship-list": { + + }, + "l-interfaces": { + "l-interface": [ + { + "interface-name": "example-interface-name-val-25679", + "interface-role": "example-interface-role-val-25679", + "v6-wan-link-ip": "example-v6-wan-link-ip-val-25679", + "selflink": "example-selflink-val-25679", + "interface-id": "example-interface-id-val-25679", + "macaddr": "example-macaddr-val-25679", + "network-name": "example-network-name-val-25679", + "resource-version": "1464193654", + "vlans": { + "vlan": [ + { + "vlan-interface": "example-vlan-interface-val-28675", + "vlan-id-inner": 22278797, + "vlan-id-outer": 22278797, + "resource-version": "1464193654", + "speed-value": "example-speed-value-val-28675", + "speed-units": "example-speed-units-val-28675", + "vlan-description": "example-vlan-description-val-28675", + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-39271", + "l3-interface-ipv4-prefix-length": 78868308, + "vlan-id-inner": 78868308, + "vlan-id-outer": 78868308, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-4005", + "l3-interface-ipv6-prefix-length": 78340763, + "vlan-id-inner": 78340763, + "vlan-id-outer": 78340763, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + } + ] + }, + "sriov-vfs": { + "sriov-vf": [ + { + "pci-id": "example-pci-id-val-85354", + "vf-vlan-filter": "example-vf-vlan-filter-val-85354", + "vf-mac-filter": "example-vf-mac-filter-val-85354", + "vf-vlan-strip": true, + "vf-vlan-anti-spoof-check": true, + "vf-mac-anti-spoof-check": true, + "vf-mirrors": "example-vf-mirrors-val-85354", + "vf-broadcast-allow": true, + "vf-unknown-multicast-allow": true, + "vf-unknown-unicast-allow": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + }, + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-21446", + "l3-interface-ipv4-prefix-length": 71127022, + "vlan-id-inner": 71127022, + "vlan-id-outer": 71127022, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-88071", + "l3-interface-ipv6-prefix-length": 55080281, + "vlan-id-inner": 55080281, + "vlan-id-outer": 55080281, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + } + ] + } + } + ] + } + } + ] + } + } +} + diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-INVALID-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-INVALID-devINT1.json new file mode 100644 index 0000000..ca97f56 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-create-AAI-INVALID-devINT1.json @@ -0,0 +1,164 @@ +{ + "cambria.partition": "AAI", + "event-header": { + "id": "20160525162737-61c49d41-5338-4755-af54-06cee9fe4acf", + "timestamp": "20160525-16:27:37:353", + "source-name": "RO", + "domain": "devINT1", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-INVALID", + "version": "v7", + "action": "CREATE", + "entity-type": "vserver", + "top-entity-type": "cloud-region", + "entity-link": "https://mtanjv9aaas03.aic.cip.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666" + }, + "entity": { + "cloud-owner": "att-aic", + "cloud-region-id": "AAIAIC25", + "tenants": { + "tenant": [ + { + "tenant-id": "example-tenant-id-val-88551", + "tenant-name": "example-tenant-name-val-88551", + "vservers": { + "vserver": [ + { + "vserver-id": "example-vserver-id-val-34666", + "vserver-name": "example-vserver-name-val-34666", + "vserver-name2": "example-vserver-name2-val-34666", + "prov-status": "PREPROV", + "vserver-selflink": "example-vserver-selflink-val-34666", + "in-maint": true, + "is-closed-loop-disabled": true, + "resource-version": "1464193654", + "volumes": { + "volume": [ + { + "volume-id": "example-volume-id-val-79195", + "volume-selflink": "example-volume-selflink-val-79195", + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + }, + "relationship-list": { + + }, + "l-interfaces": { + "l-interface": [ + { + "interface-name": "example-interface-name-val-25679", + "interface-role": "example-interface-role-val-25679", + "v6-wan-link-ip": "example-v6-wan-link-ip-val-25679", + "selflink": "example-selflink-val-25679", + "interface-id": "example-interface-id-val-25679", + "macaddr": "example-macaddr-val-25679", + "network-name": "example-network-name-val-25679", + "resource-version": "1464193654", + "vlans": { + "vlan": [ + { + "vlan-interface": "example-vlan-interface-val-28675", + "vlan-id-inner": 22278797, + "vlan-id-outer": 22278797, + "resource-version": "1464193654", + "speed-value": "example-speed-value-val-28675", + "speed-units": "example-speed-units-val-28675", + "vlan-description": "example-vlan-description-val-28675", + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-39271", + "l3-interface-ipv4-prefix-length": 78868308, + "vlan-id-inner": 78868308, + "vlan-id-outer": 78868308, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-4005", + "l3-interface-ipv6-prefix-length": 78340763, + "vlan-id-inner": 78340763, + "vlan-id-outer": 78340763, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + } + ] + }, + "sriov-vfs": { + "sriov-vf": [ + { + "pci-id": "example-pci-id-val-85354", + "vf-vlan-filter": "example-vf-vlan-filter-val-85354", + "vf-mac-filter": "example-vf-mac-filter-val-85354", + "vf-vlan-strip": true, + "vf-vlan-anti-spoof-check": true, + "vf-mac-anti-spoof-check": true, + "vf-mirrors": "example-vf-mirrors-val-85354", + "vf-broadcast-allow": true, + "vf-unknown-multicast-allow": true, + "vf-unknown-unicast-allow": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + }, + "relationship-list": { + + }, + "l3-interface-ipv4-address-list": [ + { + "l3-interface-ipv4-address": "example-l3-interface-ipv4-address-val-21446", + "l3-interface-ipv4-prefix-length": 71127022, + "vlan-id-inner": 71127022, + "vlan-id-outer": 71127022, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ], + "l3-interface-ipv6-address-list": [ + { + "l3-interface-ipv6-address": "example-l3-interface-ipv6-address-val-88071", + "l3-interface-ipv6-prefix-length": 55080281, + "vlan-id-inner": 55080281, + "vlan-id-outer": 55080281, + "is-floating": true, + "resource-version": "1464193654", + "relationship-list": { + + } + } + ] + } + ] + } + } + ] + } + } + ] + } + } +} + diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-delete-AAI-BAD123-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-delete-AAI-BAD123-devINT1.json new file mode 100644 index 0000000..3b91df8 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-delete-AAI-BAD123-devINT1.json @@ -0,0 +1,62 @@ +{ + "cambria.partition": "AAI", + "entity": { + "cloud-region-id": "AAIAIC25", + "cloud-owner": "att-aic", + "tenants": { + "tenant": [{ + "vservers": { + "vserver": [{ + "resource-version": "1476736933", + "is-closed-loop-disabled": false, + "vserver-selflink": "https://aai-app-e2e.test.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/USETEJORLFL0154UJZZ01%3A%3AuCPE-VMS/vservers/vserver/26c62277-07f4-449c-9f0a-4247ac28f944", + "vserver-name": "USETEJORLFL0154UJZZ01-USETEJORLFL0154UJTE08", + "vserver-id": "26c62277-07f4-449c-9f0a-4247ac28f944", + "in-maint": false, + "vserver-name2": "USETEJORLFL0154UJTE08", + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "e5365951-9d90-4853-afae-c34a0707e3b6" + }], + "related-to-property": [{ + "property-value": "USETEJORLFL0154UJTE08", + "property-key": "generic-vnf.vnf-name" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v8/network/generic-vnfs/generic-vnf/e5365951-9d90-4853-afae-c34a0707e3b6/", + "related-to": "generic-vnf" + }, + { + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "USETEJORLFL0154UJZZ01" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v8/cloud-infrastructure/pservers/pserver/USETEJORLFL0154UJZZ01/", + "related-to": "pserver" + }] + } + }] + }, + "tenant-id": "USETEJORLFL0154UJZZ01::uCPE-VMS" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:43:11:262", + "id": "20161017204311-000bc9ba-56f2-4934-9fe1-595c6aa5db62", + "action": "DELETE", + "domain": "devINT1", + "source-name": "SDNC", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/USETEJORLFL0154UJZZ01%3A%3AuCPE-VMS/vservers/vserver/26c62277-07f4-449c-9f0a-4247ac28f944", + "entity-type": "vserver", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-BAD123", + "top-entity-type": "cloud-region", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-devINT1.json new file mode 100644 index 0000000..2e10e29 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-devINT1.json @@ -0,0 +1,62 @@ +{ + "cambria.partition": "AAI", + "entity": { + "cloud-region-id": "AAIAIC25", + "cloud-owner": "att-aic", + "tenants": { + "tenant": [{ + "vservers": { + "vserver": [{ + "resource-version": "1476736933", + "is-closed-loop-disabled": false, + "vserver-selflink": "https://aai-app-e2e.test.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/USETEJORLFL0154UJZZ01%3A%3AuCPE-VMS/vservers/vserver/26c62277-07f4-449c-9f0a-4247ac28f944", + "vserver-name": "USETEJORLFL0154UJZZ01-USETEJORLFL0154UJTE08", + "vserver-id": "26c62277-07f4-449c-9f0a-4247ac28f944", + "in-maint": false, + "vserver-name2": "USETEJORLFL0154UJTE08", + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "e5365951-9d90-4853-afae-c34a0707e3b6" + }], + "related-to-property": [{ + "property-value": "USETEJORLFL0154UJTE08", + "property-key": "generic-vnf.vnf-name" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v8/network/generic-vnfs/generic-vnf/e5365951-9d90-4853-afae-c34a0707e3b6/", + "related-to": "generic-vnf" + }, + { + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "USETEJORLFL0154UJZZ01" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v8/cloud-infrastructure/pservers/pserver/USETEJORLFL0154UJZZ01/", + "related-to": "pserver" + }] + } + }] + }, + "tenant-id": "USETEJORLFL0154UJZZ01::uCPE-VMS" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:43:11:262", + "id": "20161017204311-000bc9ba-56f2-4934-9fe1-595c6aa5db62", + "action": "DELETE", + "domain": "devINT1", + "source-name": "SDNC", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/USETEJORLFL0154UJZZ01%3A%3AuCPE-VMS/vservers/vserver/26c62277-07f4-449c-9f0a-4247ac28f944", + "entity-type": "vserver", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "cloud-region", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-e2e1.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-e2e1.json new file mode 100644 index 0000000..5161603 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-e2e1.json @@ -0,0 +1,62 @@ +{ + "cambria.partition": "AAI", + "entity": { + "cloud-region-id": "AAIAIC25", + "cloud-owner": "att-aic", + "tenants": { + "tenant": [{ + "vservers": { + "vserver": [{ + "resource-version": "1476736933", + "is-closed-loop-disabled": false, + "vserver-selflink": "https://aai-app-e2e.test.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/USETEJORLFL0154UJZZ01%3A%3AuCPE-VMS/vservers/vserver/26c62277-07f4-449c-9f0a-4247ac28f944", + "vserver-name": "USETEJORLFL0154UJZZ01-USETEJORLFL0154UJTE08", + "vserver-id": "26c62277-07f4-449c-9f0a-4247ac28f944", + "in-maint": false, + "vserver-name2": "USETEJORLFL0154UJTE08", + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "e5365951-9d90-4853-afae-c34a0707e3b6" + }], + "related-to-property": [{ + "property-value": "USETEJORLFL0154UJTE08", + "property-key": "generic-vnf.vnf-name" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v8/network/generic-vnfs/generic-vnf/e5365951-9d90-4853-afae-c34a0707e3b6/", + "related-to": "generic-vnf" + }, + { + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "USETEJORLFL0154UJZZ01" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v8/cloud-infrastructure/pservers/pserver/USETEJORLFL0154UJZZ01/", + "related-to": "pserver" + }] + } + }] + }, + "tenant-id": "USETEJORLFL0154UJZZ01::uCPE-VMS" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:43:11:262", + "id": "20161017204311-000bc9ba-56f2-4934-9fe1-595c6aa5db62", + "action": "DELETE", + "domain": "e2e1", + "source-name": "SDNC", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/USETEJORLFL0154UJZZ01%3A%3AuCPE-VMS/vservers/vserver/26c62277-07f4-449c-9f0a-4247ac28f944", + "entity-type": "vserver", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "cloud-region", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-update-AAI-EVENT-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-update-AAI-EVENT-devINT1.json new file mode 100644 index 0000000..3576407 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-update-AAI-EVENT-devINT1.json @@ -0,0 +1,108 @@ +{ + "cambria.partition": "AAI", + "entity": { + "cloud-region-id": "AAIAIC25", + "cloud-owner": "att-aic", + "tenants": { + "tenant": [{ + "vservers": { + "vserver": [{ + "resource-version": "1476735222", + "is-closed-loop-disabled": false, + "vserver-selflink": "http://compute.rdm2.cci.att.com:8774/v2/d52b9dea5d0f4e5d90be3590ac8c78a9/servers/fd280243-cd5c-424e-b629-533cabe2a164", + "vserver-name": "vm-54", + "vserver-id": "fd280243-cd5c-424e-b629-533cabe2a164", + "in-maint": false, + "vserver-name2": "VM_54", + "l-interfaces": { + "l-interface": [{ + "resource-version": "1452288058", + "macaddr": "02:fd:59:37:be:3c", + "selflink": "http://network.rdm2.cci.att.com:9696/v2.0/ports/fd5937be-3ca4-4db0-89c9-e210bf8bf31f", + "interface-id": "fd5937be-3ca4-4db0-89c9-e210bf8bf31f", + "l3-interface-ipv4-address-list": [{ + "resource-version": "1452288058", + "l3-interface-ipv4-address": "192.168.112.56", + "neutron-network-id": "a2e5433f-38c7-420e-9c06-134ee893de3f", + "neutron-subnet-id": "b58a5b21-1f3b-42b8-93a6-109b2a700fdb", + "is-floating": false, + "l3-interface-ipv4-prefix-length": 24 + }], + "interface-name": "fd5937be-3ca4-4db0-89c9-e210bf8bf31f", + "network-name": "CinderVolumeNetwork" + }] + }, + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "image.image-id", + "relationship-value": "fc2b5df5-0e28-4c05-9e8c-75cebbd537e5" + }], + "related-to-property": [{ + "property-value": "TestVM", + "property-key": "image.image-name" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/images/image/fc2b5df5-0e28-4c05-9e8c-75cebbd537e5/", + "related-to": "image" + }, + { + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "rdm2r06c010.rdm2.cci.att.com" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v7/cloud-infrastructure/pservers/pserver/rdm2r06c010.rdm2.cci.att.com/", + "related-to": "pserver" + }, + { + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "flavor.flavor-id", + "relationship-value": "31" + }], + "related-to-property": [{ + "property-value": "m1.small", + "property-key": "flavor.flavor-name" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/flavors/flavor/31/", + "related-to": "flavor" + }] + } + }] + }, + "tenant-id": "d52b9dea5d0f4e5d90be3590ac8c78a9" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:13:45:472", + "id": "20161017201345-af157723-3835-4619-b6d8-dc16c19308bb", + "action": "UPDATE", + "domain": "devINT1", + "source-name": "RO", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/d52b9dea5d0f4e5d90be3590ac8c78a9/vservers/vserver/fd280243-cd5c-424e-b629-533cabe2a164", + "entity-type": "vserver", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "cloud-region", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-update-AAI-EVENT-testINT1.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-update-AAI-EVENT-testINT1.json new file mode 100644 index 0000000..943c7d1 --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-update-AAI-EVENT-testINT1.json @@ -0,0 +1,108 @@ +{ + "cambria.partition": "AAI", + "entity": { + "cloud-region-id": "AAIAIC25", + "cloud-owner": "att-aic", + "tenants": { + "tenant": [{ + "vservers": { + "vserver": [{ + "resource-version": "1476735222", + "is-closed-loop-disabled": false, + "vserver-selflink": "http://compute.rdm2.cci.att.com:8774/v2/d52b9dea5d0f4e5d90be3590ac8c78a9/servers/fd280243-cd5c-424e-b629-533cabe2a164", + "vserver-name": "vm-54", + "vserver-id": "fd280243-cd5c-424e-b629-533cabe2a164", + "in-maint": false, + "vserver-name2": "VM_54", + "l-interfaces": { + "l-interface": [{ + "resource-version": "1452288058", + "macaddr": "02:fd:59:37:be:3c", + "selflink": "http://network.rdm2.cci.att.com:9696/v2.0/ports/fd5937be-3ca4-4db0-89c9-e210bf8bf31f", + "interface-id": "fd5937be-3ca4-4db0-89c9-e210bf8bf31f", + "l3-interface-ipv4-address-list": [{ + "resource-version": "1452288058", + "l3-interface-ipv4-address": "192.168.112.56", + "neutron-network-id": "a2e5433f-38c7-420e-9c06-134ee893de3f", + "neutron-subnet-id": "b58a5b21-1f3b-42b8-93a6-109b2a700fdb", + "is-floating": false, + "l3-interface-ipv4-prefix-length": 24 + }], + "interface-name": "fd5937be-3ca4-4db0-89c9-e210bf8bf31f", + "network-name": "CinderVolumeNetwork" + }] + }, + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "image.image-id", + "relationship-value": "fc2b5df5-0e28-4c05-9e8c-75cebbd537e5" + }], + "related-to-property": [{ + "property-value": "TestVM", + "property-key": "image.image-name" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/images/image/fc2b5df5-0e28-4c05-9e8c-75cebbd537e5/", + "related-to": "image" + }, + { + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "rdm2r06c010.rdm2.cci.att.com" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v7/cloud-infrastructure/pservers/pserver/rdm2r06c010.rdm2.cci.att.com/", + "related-to": "pserver" + }, + { + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "flavor.flavor-id", + "relationship-value": "31" + }], + "related-to-property": [{ + "property-value": "m1.small", + "property-key": "flavor.flavor-name" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/flavors/flavor/31/", + "related-to": "flavor" + }] + } + }] + }, + "tenant-id": "d52b9dea5d0f4e5d90be3590ac8c78a9" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:13:45:472", + "id": "20161017201345-af157723-3835-4619-b6d8-dc16c19308bb", + "action": "UPDATE", + "domain": "testINT1", + "source-name": "RO", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/d52b9dea5d0f4e5d90be3590ac8c78a9/vservers/vserver/fd280243-cd5c-424e-b629-533cabe2a164", + "entity-type": "vserver", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-EVENT", + "top-entity-type": "cloud-region", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-update-AAI-TEST9-devINT1.json b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-update-AAI-TEST9-devINT1.json new file mode 100644 index 0000000..e8f189f --- /dev/null +++ b/src/integration-test/resources/system_test/data/rule-driven/vserver-tests/vserver-update-AAI-TEST9-devINT1.json @@ -0,0 +1,108 @@ +{ + "cambria.partition": "AAI", + "entity": { + "cloud-region-id": "AAIAIC25", + "cloud-owner": "att-aic", + "tenants": { + "tenant": [{ + "vservers": { + "vserver": [{ + "resource-version": "1476735222", + "is-closed-loop-disabled": false, + "vserver-selflink": "http://compute.rdm2.cci.att.com:8774/v2/d52b9dea5d0f4e5d90be3590ac8c78a9/servers/fd280243-cd5c-424e-b629-533cabe2a164", + "vserver-name": "vm-54", + "vserver-id": "fd280243-cd5c-424e-b629-533cabe2a164", + "in-maint": false, + "vserver-name2": "VM_54", + "l-interfaces": { + "l-interface": [{ + "resource-version": "1452288058", + "macaddr": "02:fd:59:37:be:3c", + "selflink": "http://network.rdm2.cci.att.com:9696/v2.0/ports/fd5937be-3ca4-4db0-89c9-e210bf8bf31f", + "interface-id": "fd5937be-3ca4-4db0-89c9-e210bf8bf31f", + "l3-interface-ipv4-address-list": [{ + "resource-version": "1452288058", + "l3-interface-ipv4-address": "192.168.112.56", + "neutron-network-id": "a2e5433f-38c7-420e-9c06-134ee893de3f", + "neutron-subnet-id": "b58a5b21-1f3b-42b8-93a6-109b2a700fdb", + "is-floating": false, + "l3-interface-ipv4-prefix-length": 24 + }], + "interface-name": "fd5937be-3ca4-4db0-89c9-e210bf8bf31f", + "network-name": "CinderVolumeNetwork" + }] + }, + "relationship-list": { + "relationship": [{ + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "image.image-id", + "relationship-value": "fc2b5df5-0e28-4c05-9e8c-75cebbd537e5" + }], + "related-to-property": [{ + "property-value": "TestVM", + "property-key": "image.image-name" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/images/image/fc2b5df5-0e28-4c05-9e8c-75cebbd537e5/", + "related-to": "image" + }, + { + "relationship-data": [{ + "relationship-key": "pserver.hostname", + "relationship-value": "rdm2r06c010.rdm2.cci.att.com" + }], + "related-to-property": [{ + "property-key": "pserver.pserver-name2" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v7/cloud-infrastructure/pservers/pserver/rdm2r06c010.rdm2.cci.att.com/", + "related-to": "pserver" + }, + { + "relationship-data": [{ + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "att-aic" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "AAIAIC25" + }, + { + "relationship-key": "flavor.flavor-id", + "relationship-value": "31" + }], + "related-to-property": [{ + "property-value": "m1.small", + "property-key": "flavor.flavor-name" + }], + "related-link": "https://aai-app-e2e.test.att.com:8443/aai/v7/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/flavors/flavor/31/", + "related-to": "flavor" + }] + } + }] + }, + "tenant-id": "d52b9dea5d0f4e5d90be3590ac8c78a9" + }] + } + }, + "event-header": { + "timestamp": "20161017-20:13:45:472", + "id": "20161017201345-af157723-3835-4619-b6d8-dc16c19308bb", + "action": "UPDATE", + "domain": "devINT1", + "source-name": "RO", + "entity-link": "https://aai-app.mtcnj.ecomp.cci.att.com:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/d52b9dea5d0f4e5d90be3590ac8c78a9/vservers/vserver/fd280243-cd5c-424e-b629-533cabe2a164", + "entity-type": "vserver", + "sequence-number": "0", + "severity": "NORMAL", + "event-type": "AAI-TEST9", + "top-entity-type": "cloud-region", + "version": "v8" + } +} diff --git a/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-excess-metadata.exp.json b/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-excess-metadata.exp.json new file mode 100644 index 0000000..9b8ef0a --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-excess-metadata.exp.json @@ -0,0 +1,509 @@ +{ + "validationId": "VALIDATIONID", + "validationTimestamp": "TIMESTAMP", + "entityId": { + "resource-instance-id": "100559" + }, + "entityType": "connector", + "entityLink": "business/connectors/connector/100559", + "resourceVersion": "1465571381", + "entity": { + "model-name": "NetBond WAN Connector v0.1", + "connector": { + "resource-instance-id": "100559", + "resource-version": "1465571381", + "persona-model-id": "dc700a83-c507-47d9-b775-1fdfcdd5f9eb", + "persona-model-version": "0.1" + }, + "extra-properties": { + "metadatum": [ + { + "metaname": "vpn-id", + "metaval": "vpn-id value 1", + "resource-version": "1466418452" + }, + { + "metaname": "unexpected", + "metaval": "unexpected value 1", + "resource-version": "1466418452" + }, + { + "metaname": "null", + "metaval": "null", + "resource-version": "1466418452" + } + ] + }, + "inventory-response-items": { + "inventory-response-item": [ + { + "virtual-data-center": { + "vdc-id": "15001220", + "vdc-name": "SAN_DIEGO_CA01", + "resource-version": "1465571382" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "sn6ca391ve2-xe-10/2/3.117|sn4ca01pbg", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "sn4ca01pbg", + "in-maint": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca391ve2-ae6.1322|dbzx0003v", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-2883", + "vnf-name": "dbzx0004v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978155" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca392ve2-ae6.1322|dbzx0003v", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-2883", + "vnf-name": "dbzx0004v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978155" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca392ve2-ae6.1927|asbg0003v", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-9320", + "vnf-name": "asbg0003v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.193.152.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "sn6ca392ve2-xe-10/2/3.117|sn4ca01pbg", + "link-type": "l2bridge", + "resource-version": "1465571382", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "sn4ca01pbg", + "in-maint": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "sn6ca391ve2-ae6.1927|asbg0003v", + "link-type": "l2bridge", + "resource-version": "1465571381", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-9320", + "vnf-name": "asbg0003v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.193.152.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978156" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + } + ] + } + }, + { + "virtual-data-center": { + "vdc-id": "15001219", + "vdc-name": "ALPHARETTA_GA01", + "resource-version": "1465571380" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga392ve2-ae6.1322|dbzx0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-1883", + "vnf-name": "dbzx0003v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga391ve2-ae6.1322|dbzx0004v", + "link-type": "l2bridge", + "resource-version": "1465571379", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-1883", + "vnf-name": "dbzx0003v", + "vnf-type": "vSRX vDBE-V VNF", + "service-id": "12a96a9d-4b4c-4349-a950-fe1159602621", + "prov-status": "ACTIVE", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga392ve2-ae6.1927|asbg0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-5305", + "vnf-name": "asbg0004v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.190.182.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978152" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "alrga391ve2-xe-10/2/3.117|ar4ga01pbg", + "link-type": "l2bridge", + "resource-version": "1465571379", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "ar4ga01pbg", + "in-maint": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "VL ELAN", + "logical-link": { + "link-name": "alrga391ve2-ae6.1927|asbg0004v", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "932518e5-4260-4cc4-8038-df604a367f85", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "vDbe", + "generic-vnf": { + "vnf-id": "VAPP-5305", + "vnf-name": "asbg0004v", + "vnf-type": "ASBGv No TLS", + "service-id": "c7611ebe-c324-48f1-8085-94aef0c6ef3d", + "prov-status": "PROV", + "ipv4-oam-address": "135.190.182.168", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1470978152" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + }, + { + "model-name": "vLAN on a Physical Wire", + "logical-link": { + "link-name": "alrga392ve2-xe-10/2/3.117|ar4ga01pbg", + "link-type": "l2bridge", + "resource-version": "1465571380", + "persona-model-id": "32bee148-2cae-4f3d-a42e-22c9e4f078a2", + "persona-model-version": "1" + }, + "extra-properties": {}, + "inventory-response-items": { + "inventory-response-item": [ + { + "model-name": "pBgf", + "pserver": { + "hostname": "ar4ga01pbg", + "in-maint": false, + "resource-version": "1470978153" + }, + "extra-properties": {}, + "inventory-response-items": {} + } + ] + } + } + ] + } + } + ] + } + }, + "violations": [ + { + "violationId": "0cf4e03f051748acd162f68e43eaacf09968243c6bb209bc95da7fb234c1af7c", + "modelName": "NetBond WAN Connector v0.1", + "category": "UNEXPECTED_REL", + "severity": "CRITICAL", + "violationType": "Model", + "violationDetails": { + "UNEXPECTED REL": "VL ELAN", + "modelName": null, + "entityType": "virtual-data-center", + "entityId": { + "vdc-id": "15001220" + } + }, + "errorMessage": "Entity [vdc-id=15001220] of type [virtual-data-center] must not be related to [VL ELAN]" + }, + { + "violationId": "653480197744c01c52922df503a3f4cce1d16b34a4247e1a81bb0eff0ab03cd6", + "modelName": "NetBond WAN Connector v0.1", + "category": "UNEXPECTED_REL", + "severity": "CRITICAL", + "violationType": "Model", + "violationDetails": { + "UNEXPECTED REL": "vLAN on a Physical Wire", + "modelName": null, + "entityType": "virtual-data-center", + "entityId": { + "vdc-id": "15001220" + } + }, + "errorMessage": "Entity [vdc-id=15001220] of type [virtual-data-center] must not be related to [vLAN on a Physical Wire]" + }, + { + "violationId": "95872761d88727334c8d1e90a08b52166314983580af659ff40fc1e169f1bbe5", + "modelName": "NetBond WAN Connector v0.1", + "category": "UNEXPECTED_REL", + "severity": "CRITICAL", + "violationType": "Model", + "violationDetails": { + "UNEXPECTED REL": "VL ELAN", + "modelName": null, + "entityType": "virtual-data-center", + "entityId": { + "vdc-id": "15001219" + } + }, + "errorMessage": "Entity [vdc-id=15001219] of type [virtual-data-center] must not be related to [VL ELAN]" + }, + { + "violationId": "5a5fcce8c6e13ecf25f28d1ef84323705b85188e506b744383af087bdda131e1", + "modelName": "NetBond WAN Connector v0.1", + "category": "UNEXPECTED_REL", + "severity": "CRITICAL", + "violationType": "Model", + "violationDetails": { + "UNEXPECTED REL": "vLAN on a Physical Wire", + "modelName": null, + "entityType": "virtual-data-center", + "entityId": { + "vdc-id": "15001219" + } + }, + "errorMessage": "Entity [vdc-id=15001219] of type [virtual-data-center] must not be related to [vLAN on a Physical Wire]" + }, + { + "violationId": "e14b5cc1094af86d3c4ebfa8bb86e41aa2f14a6b8d2b15d1126cd15f097e9bed", + "modelName": "NetBond WAN Connector v0.1", + "category": "MISSING_ATTR", + "severity": "CRITICAL", + "violationType": "Model", + "violationDetails": { + "MISSING ATTR": "product" + }, + "errorMessage": "Attribute [product] is missing in the object instance" + }, + { + "violationId": "143ec2f2e5450d183a5c4e4f66c55e54d47bcf36c314f74ef6d32112c61a890e", + "modelName": "NetBond WAN Connector v0.1", + "category": "UNEXPECTED_ATTR", + "severity": "CRITICAL", + "violationType": "Model", + "violationDetails": { + "UNEXPECTED ATTR": "null" + }, + "errorMessage": "Attribute [null] should not be present in the object instance" + }, + { + "violationId": "a672399f306036be2085a1eaf18027921e2c44790ffbcd0f92ce40ce0e1853b6", + "modelName": "NetBond WAN Connector v0.1", + "category": "UNEXPECTED_ATTR", + "severity": "CRITICAL", + "violationType": "Model", + "violationDetails": { + "UNEXPECTED ATTR": "unexpected" + }, + "errorMessage": "Attribute [unexpected] should not be present in the object instance" + } + ] +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-missing-attribute.exp.json b/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-missing-attribute.exp.json new file mode 100644 index 0000000..716706a --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-missing-attribute.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"resource-instance-id":"100559"},"entityType":"connector","entityLink":"business/connectors/connector/100559","resourceVersion":"1465571381","entity":{"model-name":"NetBond WAN Connector v0.1","connector":{"resource-instance-id":"100559","resource-version":"1465571381","persona-model-id":"dc700a83-c507-47d9-b775-1fdfcdd5f9eb","persona-model-version":"0.1"},"extra-properties":{"metadatum":[{"metaname":"vpn-id","metaval":"vpn-id value 1","resource-version":"1466418452"},{"metaname":"unexpected","metaval":"unexpected value 1","resource-version":"1466418452"}]},"inventory-response-items":{"inventory-response-item":[{"virtual-data-center":{"vdc-id":"15001220","vdc-name":"SAN_DIEGO_CA01","resource-version":"1465571382"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"sn6ca391ve2-xe-10/2/3.117|sn4ca01pbg","link-type":"l2bridge","resource-version":"1465571381","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"sn4ca01pbg","in-maint":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca391ve2-ae6.1322|dbzx0003v","link-type":"l2bridge","resource-version":"1465571381","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-2883","vnf-name":"dbzx0004v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978155"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca392ve2-ae6.1322|dbzx0003v","link-type":"l2bridge","resource-version":"1465571382","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-2883","vnf-name":"dbzx0004v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978155"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca392ve2-ae6.1927|asbg0003v","link-type":"l2bridge","resource-version":"1465571382","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-9320","vnf-name":"asbg0003v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.193.152.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"sn6ca392ve2-xe-10/2/3.117|sn4ca01pbg","link-type":"l2bridge","resource-version":"1465571382","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"sn4ca01pbg","in-maint":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca391ve2-ae6.1927|asbg0003v","link-type":"l2bridge","resource-version":"1465571381","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-9320","vnf-name":"asbg0003v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.193.152.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}}]}},{"virtual-data-center":{"vdc-id":"15001219","vdc-name":"ALPHARETTA_GA01","resource-version":"1465571380"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"VL ELAN","logical-link":{"link-name":"alrga392ve2-ae6.1322|dbzx0004v","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-1883","vnf-name":"dbzx0003v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"alrga391ve2-ae6.1322|dbzx0004v","link-type":"l2bridge","resource-version":"1465571379","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-1883","vnf-name":"dbzx0003v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"alrga392ve2-ae6.1927|asbg0004v","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-5305","vnf-name":"asbg0004v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.190.182.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978152"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"alrga391ve2-xe-10/2/3.117|ar4ga01pbg","link-type":"l2bridge","resource-version":"1465571379","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"ar4ga01pbg","in-maint":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"alrga391ve2-ae6.1927|asbg0004v","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-5305","vnf-name":"asbg0004v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.190.182.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978152"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"alrga392ve2-xe-10/2/3.117|ar4ga01pbg","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"ar4ga01pbg","in-maint":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}}]}}]}},"violations":[{"violationId":"0cf4e03f051748acd162f68e43eaacf09968243c6bb209bc95da7fb234c1af7c","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"VL ELAN","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001220"}},"errorMessage":"Entity [vdc-id=15001220] of type [virtual-data-center] must not be related to [VL ELAN]"},{"violationId":"653480197744c01c52922df503a3f4cce1d16b34a4247e1a81bb0eff0ab03cd6","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"vLAN on a Physical Wire","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001220"}},"errorMessage":"Entity [vdc-id=15001220] of type [virtual-data-center] must not be related to [vLAN on a Physical Wire]"},{"violationId":"95872761d88727334c8d1e90a08b52166314983580af659ff40fc1e169f1bbe5","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"VL ELAN","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001219"}},"errorMessage":"Entity [vdc-id=15001219] of type [virtual-data-center] must not be related to [VL ELAN]"},{"violationId":"5a5fcce8c6e13ecf25f28d1ef84323705b85188e506b744383af087bdda131e1","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"vLAN on a Physical Wire","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001219"}},"errorMessage":"Entity [vdc-id=15001219] of type [virtual-data-center] must not be related to [vLAN on a Physical Wire]"},{"violationId":"e14b5cc1094af86d3c4ebfa8bb86e41aa2f14a6b8d2b15d1126cd15f097e9bed","modelName":"NetBond WAN Connector v0.1","category":"MISSING_ATTR","severity":"CRITICAL","violationType":"Model","violationDetails":{"MISSING ATTR":"product"},"errorMessage":"Attribute [product] is missing in the object instance"},{"violationId":"a672399f306036be2085a1eaf18027921e2c44790ffbcd0f92ce40ce0e1853b6","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_ATTR","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED ATTR":"unexpected"},"errorMessage":"Attribute [unexpected] should not be present in the object instance"}]} diff --git a/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-no-metadata.exp.json b/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-no-metadata.exp.json new file mode 100644 index 0000000..765ec19 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-no-metadata.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"resource-instance-id":"100559"},"entityType":"connector","entityLink":"business/connectors/connector/100559","resourceVersion":"1465571381","entity":{"model-name":"NetBond WAN Connector v0.1","connector":{"resource-instance-id":"100559","resource-version":"1465571381","persona-model-id":"dc700a83-c507-47d9-b775-1fdfcdd5f9eb","persona-model-version":"0.1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"virtual-data-center":{"vdc-id":"15001220","vdc-name":"SAN_DIEGO_CA01","resource-version":"1465571382"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"sn6ca391ve2-xe-10/2/3.117|sn4ca01pbg","link-type":"l2bridge","resource-version":"1465571381","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"sn4ca01pbg","in-maint":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca391ve2-ae6.1322|dbzx0003v","link-type":"l2bridge","resource-version":"1465571381","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-2883","vnf-name":"dbzx0004v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978155"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca392ve2-ae6.1322|dbzx0003v","link-type":"l2bridge","resource-version":"1465571382","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-2883","vnf-name":"dbzx0004v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978155"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca392ve2-ae6.1927|asbg0003v","link-type":"l2bridge","resource-version":"1465571382","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-9320","vnf-name":"asbg0003v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.193.152.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"sn6ca392ve2-xe-10/2/3.117|sn4ca01pbg","link-type":"l2bridge","resource-version":"1465571382","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"sn4ca01pbg","in-maint":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca391ve2-ae6.1927|asbg0003v","link-type":"l2bridge","resource-version":"1465571381","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-9320","vnf-name":"asbg0003v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.193.152.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}}]}},{"virtual-data-center":{"vdc-id":"15001219","vdc-name":"ALPHARETTA_GA01","resource-version":"1465571380"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"VL ELAN","logical-link":{"link-name":"alrga392ve2-ae6.1322|dbzx0004v","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-1883","vnf-name":"dbzx0003v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"alrga391ve2-ae6.1322|dbzx0004v","link-type":"l2bridge","resource-version":"1465571379","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-1883","vnf-name":"dbzx0003v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"alrga392ve2-ae6.1927|asbg0004v","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-5305","vnf-name":"asbg0004v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.190.182.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978152"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"alrga391ve2-xe-10/2/3.117|ar4ga01pbg","link-type":"l2bridge","resource-version":"1465571379","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"ar4ga01pbg","in-maint":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"alrga391ve2-ae6.1927|asbg0004v","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-5305","vnf-name":"asbg0004v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.190.182.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978152"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"alrga392ve2-xe-10/2/3.117|ar4ga01pbg","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"ar4ga01pbg","in-maint":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}}]}}]}},"violations":[{"violationId":"0cf4e03f051748acd162f68e43eaacf09968243c6bb209bc95da7fb234c1af7c","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"VL ELAN","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001220"}},"errorMessage":"Entity [vdc-id=15001220] of type [virtual-data-center] must not be related to [VL ELAN]"},{"violationId":"653480197744c01c52922df503a3f4cce1d16b34a4247e1a81bb0eff0ab03cd6","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"vLAN on a Physical Wire","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001220"}},"errorMessage":"Entity [vdc-id=15001220] of type [virtual-data-center] must not be related to [vLAN on a Physical Wire]"},{"violationId":"95872761d88727334c8d1e90a08b52166314983580af659ff40fc1e169f1bbe5","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"VL ELAN","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001219"}},"errorMessage":"Entity [vdc-id=15001219] of type [virtual-data-center] must not be related to [VL ELAN]"},{"violationId":"5a5fcce8c6e13ecf25f28d1ef84323705b85188e506b744383af087bdda131e1","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"vLAN on a Physical Wire","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001219"}},"errorMessage":"Entity [vdc-id=15001219] of type [virtual-data-center] must not be related to [vLAN on a Physical Wire]"},{"violationId":"e14b5cc1094af86d3c4ebfa8bb86e41aa2f14a6b8d2b15d1126cd15f097e9bed","modelName":"NetBond WAN Connector v0.1","category":"MISSING_ATTR","severity":"CRITICAL","violationType":"Model","violationDetails":{"MISSING ATTR":"product"},"errorMessage":"Attribute [product] is missing in the object instance"},{"violationId":"3c337b5328422b9820a6f4e4ff13ddead3af2fe9f901ec955e9b47b5625d12c6","modelName":"NetBond WAN Connector v0.1","category":"MISSING_ATTR","severity":"CRITICAL","violationType":"Model","violationDetails":{"MISSING ATTR":"vpn-id"},"errorMessage":"Attribute [vpn-id] is missing in the object instance"}]} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-no-model.exp.json b/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-no-model.exp.json new file mode 100644 index 0000000..fe16944 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-no-model.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"resource-instance-id":"c7611ebe-c324-48f1-8085-94aef0c12fd"},"entityType":"connector","entityLink":"business/connectors/connector/100559","resourceVersion":"1467975776","violations":[{"violationId":"7affd6606c9ade9cd4d8d0fbf2089b86516f1223fe108a26c6f8ccd27bc9dfd8","modelName":null,"category":"NO_MODEL","severity":"CRITICAL","violationType":"Model","violationDetails":{"No model ID":"invalid-model-id"},"errorMessage":"The model [invalid-model-id] could not be found"}]} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-valid.exp.json b/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-valid.exp.json new file mode 100644 index 0000000..ab3cfb9 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/model-driven/connector/connector-create-valid.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"resource-instance-id":"100559"},"entityType":"connector","entityLink":"business/connectors/connector/100559","resourceVersion":"1465571381","entity":{"model-name":"NetBond WAN Connector v0.1","connector":{"resource-instance-id":"100559","resource-version":"1465571381","persona-model-id":"dc700a83-c507-47d9-b775-1fdfcdd5f9eb","persona-model-version":"0.1"},"extra-properties":{"metadatum":[{"metaname":"vpn-id","metaval":"vpn-id-value-1","resource-version":"1465990410"},{"metaname":"product","metaval":"product-value-1","resource-version":"1465990410"}]},"inventory-response-items":{"inventory-response-item":[{"virtual-data-center":{"vdc-id":"15001220","vdc-name":"SAN_DIEGO_CA01","resource-version":"1465571382"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"sn6ca391ve2-xe-10/2/3.117|sn4ca01pbg","link-type":"l2bridge","resource-version":"1465571381","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"sn4ca01pbg","in-maint":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca391ve2-ae6.1322|dbzx0003v","link-type":"l2bridge","resource-version":"1465571381","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-2883","vnf-name":"dbzx0004v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978155"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca392ve2-ae6.1322|dbzx0003v","link-type":"l2bridge","resource-version":"1465571382","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-2883","vnf-name":"dbzx0004v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978155"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca392ve2-ae6.1927|asbg0003v","link-type":"l2bridge","resource-version":"1465571382","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-9320","vnf-name":"asbg0003v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.193.152.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"sn6ca392ve2-xe-10/2/3.117|sn4ca01pbg","link-type":"l2bridge","resource-version":"1465571382","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"sn4ca01pbg","in-maint":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"sn6ca391ve2-ae6.1927|asbg0003v","link-type":"l2bridge","resource-version":"1465571381","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-9320","vnf-name":"asbg0003v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.193.152.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978156"},"extra-properties":{},"inventory-response-items":{}}]}}]}},{"virtual-data-center":{"vdc-id":"15001219","vdc-name":"ALPHARETTA_GA01","resource-version":"1465571380"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"VL ELAN","logical-link":{"link-name":"alrga392ve2-ae6.1322|dbzx0004v","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-1883","vnf-name":"dbzx0003v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"alrga391ve2-ae6.1322|dbzx0004v","link-type":"l2bridge","resource-version":"1465571379","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-1883","vnf-name":"dbzx0003v","vnf-type":"vSRX vDBE-V VNF","service-id":"12a96a9d-4b4c-4349-a950-fe1159602621","prov-status":"ACTIVE","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"alrga392ve2-ae6.1927|asbg0004v","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-5305","vnf-name":"asbg0004v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.190.182.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978152"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"alrga391ve2-xe-10/2/3.117|ar4ga01pbg","link-type":"l2bridge","resource-version":"1465571379","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"ar4ga01pbg","in-maint":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"VL ELAN","logical-link":{"link-name":"alrga391ve2-ae6.1927|asbg0004v","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"932518e5-4260-4cc4-8038-df604a367f85","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"vDbe","generic-vnf":{"vnf-id":"VAPP-5305","vnf-name":"asbg0004v","vnf-type":"ASBGv No TLS","service-id":"c7611ebe-c324-48f1-8085-94aef0c6ef3d","prov-status":"PROV","ipv4-oam-address":"135.190.182.168","in-maint":false,"is-closed-loop-disabled":false,"resource-version":"1470978152"},"extra-properties":{},"inventory-response-items":{}}]}},{"model-name":"vLAN on a Physical Wire","logical-link":{"link-name":"alrga392ve2-xe-10/2/3.117|ar4ga01pbg","link-type":"l2bridge","resource-version":"1465571380","persona-model-id":"32bee148-2cae-4f3d-a42e-22c9e4f078a2","persona-model-version":"1"},"extra-properties":{},"inventory-response-items":{"inventory-response-item":[{"model-name":"pBgf","pserver":{"hostname":"ar4ga01pbg","in-maint":false,"resource-version":"1470978153"},"extra-properties":{},"inventory-response-items":{}}]}}]}}]}},"violations":[{"violationId":"0cf4e03f051748acd162f68e43eaacf09968243c6bb209bc95da7fb234c1af7c","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"VL ELAN","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001220"}},"errorMessage":"Entity [vdc-id=15001220] of type [virtual-data-center] must not be related to [VL ELAN]"},{"violationId":"653480197744c01c52922df503a3f4cce1d16b34a4247e1a81bb0eff0ab03cd6","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"vLAN on a Physical Wire","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001220"}},"errorMessage":"Entity [vdc-id=15001220] of type [virtual-data-center] must not be related to [vLAN on a Physical Wire]"},{"violationId":"95872761d88727334c8d1e90a08b52166314983580af659ff40fc1e169f1bbe5","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"VL ELAN","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001219"}},"errorMessage":"Entity [vdc-id=15001219] of type [virtual-data-center] must not be related to [VL ELAN]"},{"violationId":"5a5fcce8c6e13ecf25f28d1ef84323705b85188e506b744383af087bdda131e1","modelName":"NetBond WAN Connector v0.1","category":"UNEXPECTED_REL","severity":"CRITICAL","violationType":"Model","violationDetails":{"UNEXPECTED REL":"vLAN on a Physical Wire","modelName":null,"entityType":"virtual-data-center","entityId":{"vdc-id":"15001219"}},"errorMessage":"Entity [vdc-id=15001219] of type [virtual-data-center] must not be related to [vLAN on a Physical Wire]"}]} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-bad-network-name.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-bad-network-name.exp.json new file mode 100644 index 0000000..b29441d --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-bad-network-name.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"physical-location-id":"MTWNJZZZLCP"},"entityType":"complex","entityLink":"network/newvces/newvce/7150963a-9054-4046-a285-a572edf2deb6","resourceVersion":"1463283799","violations":[{"violationId":"ad1027efffbd7bd811f7cb13d806d0a1c279fe8a660318994bb103ecd8644837","modelName":null,"category":"INVALID_NAME","severity":"MINOR","violationType":"Rule","validationRule":"if a customer is related to an oam-network then oam-network.network-name must match naming convention","violationDetails":{"relationship-list.relationship[*]":[{"related-to":"pserver","related-link":"https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/mtznj101snd/","relationship-data":[{"relationship-key":"pserver.hostname","relationship-value":"mtznj101snd"}],"related-to-property":[{"property-key":"pserver.pserver-name2"}]},{"related-to":"pserver","related-link":"https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/mtznjtax101/","relationship-data":[{"relationship-key":"pserver.hostname","relationship-value":"mtznjtax101"}],"related-to-property":[{"property-key":"pserver.pserver-name2"}]},{"related-to":"vce","related-link":"https://135.16.121.249:8443/aai/v8/network/vces/vce/19a2ac02-bed0-4d84-a751-6dffffffffff/","relationship-data":[{"relationship-key":"vce.vnf-id","relationship-value":"19a2ac02-bed0-4d84-a751-6dffffffffff"}],"related-to-property":[{"property-key":"vce.vnf-name","property-value":"mtznj431vbc"}]},{"related-to":"pserver","related-link":"https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/mtznj125snd/","relationship-data":[{"relationship-key":"pserver.hostname","relationship-value":"mtznj125snd"}],"related-to-property":[{"property-key":"pserver.pserver-name2"}]},{"related-to":"oam-network","related-link":"https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/oam-networks/oam-network/ca084d91-ffff-ffff-a1bf-a8a7f1969f80/","relationship-data":[{"relationship-key":"cloud-region.cloud-owner","relationship-value":"att-aic"},{"relationship-key":"cloud-region.cloud-region-id","relationship-value":"AAIAIC25"},{"relationship-key":"oam-network.network-uuid","relationship-value":"ca084d91-ffff-ffff-a1bf-a8a7f1969f80"}],"related-to-property":[{"property-key":"oam-network.network-name","property-value":"MARK-OAM-1323"}]},{"related-to":"availability-zone","related-link":"https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/availability-zones/availability-zone/mtznj-esx-az01/","relationship-data":[{"relationship-key":"cloud-region.cloud-owner","relationship-value":"att-aic"},{"relationship-key":"cloud-region.cloud-region-id","relationship-value":"AAIAIC25"},{"relationship-key":"availability-zone.availability-zone-name","relationship-value":"mtznj-esx-az01"}]}]},"errorMessage":"Invalid name - if a customer is related to an oam-network then network-name must start with VLAN"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-badCLLI-missingREL.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-badCLLI-missingREL.exp.json new file mode 100644 index 0000000..53256a5 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-badCLLI-missingREL.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"physical-location-id":"dhv-test-complex"},"entityType":"complex","entityLink":"cloud-infrastructure/complexes/complex/dhv-test-complex/","resourceVersion":"1473996687","violations":[{"violationId":"e030ca439e34511e28b7cef026bbc23735297043b93047507ea2b65343c84f33","modelName":null,"category":"FIELD_LENGTH","severity":"CRITICAL","violationType":"Rule","validationRule":"CLLI","violationDetails":{"physical-location-id":"dhv-test-complex"},"errorMessage":"Invalid length - field must be 8 or 11 characters long"},{"violationId":"b4ef82f099793189db42a372a950776e2214da7aa1824d874044473fef8fddfd","modelName":null,"category":"MISSING_REL","severity":"CRITICAL","violationType":"Rule","validationRule":"complex is related to availability zone","violationDetails":{"relationship-list.relationship[*].related-to":["pserver"]},"errorMessage":"Missing relationship - a complex must be related to an availability zone"},{"violationId":"2ee7e28ba76634d936775d646af5a4035206ed44ccee4de90085a6fc08f2483a","modelName":null,"category":"MISSING_REL","severity":"MAJOR","violationType":"Rule","validationRule":"complex is related to 1 oam-network","violationDetails":{"relationship-list.relationship[*].related-to":["pserver"]},"errorMessage":"Missing relationship - complex must be related to 1 oam-network"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-good-network-name.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-good-network-name.exp.json new file mode 100644 index 0000000..42eb2d3 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/complexes/complexes-update-AAI-EVENT-devINT1-good-network-name.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"physical-location-id":"MTWNJZZZLCP"},"entityType":"complex","entityLink":"network/newvces/newvce/7150963a-9054-4046-a285-a572edf2deb6","resourceVersion":"1463283799","violations":[]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/edge-cases/empty-payload.error b/src/integration-test/resources/system_test/results/expected/rule-driven/edge-cases/empty-payload.error new file mode 100644 index 0000000..72ba7fc --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/edge-cases/empty-payload.error @@ -0,0 +1 @@ +VS-500, JSON could not be parsed.; Caused by: json string can not be null or empty diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/edge-cases/plain-text-payload.error b/src/integration-test/resources/system_test/results/expected/rule-driven/edge-cases/plain-text-payload.error new file mode 100644 index 0000000..6d125b7 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/edge-cases/plain-text-payload.error @@ -0,0 +1 @@ +VS-500, JSON could not be parsed.; Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 8 path $ diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/empty-ruleset/spike-pserver-create-update.error b/src/integration-test/resources/system_test/results/expected/rule-driven/empty-ruleset/spike-pserver-create-update.error new file mode 100644 index 0000000..2b580e2 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/empty-ruleset/spike-pserver-create-update.error @@ -0,0 +1 @@ +VS-102, Event type EMPTY-RULESET-EVENT has no rule definitions. \ No newline at end of file diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-bad-ipv4.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-bad-ipv4.exp.json new file mode 100644 index 0000000..227dfe8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-bad-ipv4.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"vnf-id":"ibcx0003v"},"entityType":"generic-vnf","entityLink":"network/generic-vnfs/generic-vnf/ibcx0003v/","resourceVersion":"1476738499","violations":[{"violationId":"fb2ad02e225adb4eb964b679308e5af7698f6584998368a01ab15b91f0c2310f","modelName":null,"category":"INVALID_VALUE","severity":"MINOR","violationType":"Rule","validationRule":"valid_ipv4_addr","violationDetails":{"ipv4-oam-address":"www.somecompany.com"},"errorMessage":"Invalid value - attribute is not a valid IPv4 address"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-good-ipv4.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-good-ipv4.exp.json new file mode 100644 index 0000000..83c8c53 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-good-ipv4.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"vnf-id":"ibcx0003v"},"entityType":"generic-vnf","entityLink":"network/generic-vnfs/generic-vnf/ibcx0003v/","resourceVersion":"1476738999","violations":[]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-missing-ipv4.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-missing-ipv4.exp.json new file mode 100644 index 0000000..eff0958 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/generic-vnf/generic-vnf-update-AAI-EVENT-devINT1-missing-ipv4.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"vnf-id":"ibcx0003v"},"entityType":"generic-vnf","entityLink":"network/generic-vnfs/generic-vnf/ibcx0003v/","resourceVersion":"1476738439","violations":[{"violationId":"ff6ccec70d8c000fb29286b5ee680d0f9ac01efde0151c5a4abe569bb8babaab","modelName":null,"category":"INVALID_VALUE","severity":"MINOR","violationType":"Rule","validationRule":"valid_ipv4_addr","violationDetails":{"ipv4-oam-address":null},"errorMessage":"Invalid value - attribute is not a valid IPv4 address"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/gizmo/gizmo-pserver-create-event.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/gizmo/gizmo-pserver-create-event.exp.json new file mode 100644 index 0000000..12c8aa0 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/gizmo/gizmo-pserver-create-event.exp.json @@ -0,0 +1,34 @@ +{ + "validationId": "0fef6730-0f32-4464-8156-4b645f135180", + "validationTimestamp": "20180306T090606Z", + "entityId": { + "hostname": "myhost" + }, + "entityType": "pserver", + "entityLink": "", + "resourceVersion": "1477013499", + "entity": { + "timestamp": 1514927928167, + "operation": "CREATE", + "vertex": { + "properties": { + "ipv4-oam-address": "1.2.3.4", + "resource-version": "1477013499", + "purpose": "my-purpose", + "fqdn": "myhost.onap.net", + "in-maint": false, + "equip-model": "DL380p-nd", + "equip-vendor": "HP", + "equip-type": "server", + "hostname": "myhost", + "ptnii-equip-name": "e-name" + }, + "key": "", + "type": "pserver", + "schema-version": "vX" + }, + "transaction-id": "c0a81fa7-5ef4-49cd-ab39-e42c53c9b9a4", + "database-transaction-id": "b3e2853e-f643-47a3-a0c3-cb54cc997ad3" + }, + "violations": [] +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/newvce/newvce-INVALID-ACTION-AAI-EVENT-devINT1.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/newvce/newvce-INVALID-ACTION-AAI-EVENT-devINT1.exp.json new file mode 100644 index 0000000..fa1bc40 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/newvce/newvce-INVALID-ACTION-AAI-EVENT-devINT1.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"vnf-id2":"7150963a-9054-4046-a285-a572edf2deb6"},"entityType":"newvce","entityLink":"network/newvces/newvce/7150963a-9054-4046-a285-a572edf2deb6","resourceVersion":"1476737775","violations":[{"violationId":"8df2499ea280a7f8de25047c433f5aaff2d13b34eef249caea92dce2a1b4d9a5","modelName":null,"category":"INVALID_VALUE","severity":"MINOR","violationType":"Rule","validationRule":"heat-stack-id equals first 11 bytes of vnf-name","violationDetails":{"heat-stack-id":null,"vnf-name":"mtjnj484vbc"},"errorMessage":"Invalid value - the value of heat-stack-id must equal the first 11 bytes of vnf-name"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/newvce/newvce-update-AAI-EVENT-devINT1.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/newvce/newvce-update-AAI-EVENT-devINT1.exp.json new file mode 100644 index 0000000..fa1bc40 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/newvce/newvce-update-AAI-EVENT-devINT1.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"vnf-id2":"7150963a-9054-4046-a285-a572edf2deb6"},"entityType":"newvce","entityLink":"network/newvces/newvce/7150963a-9054-4046-a285-a572edf2deb6","resourceVersion":"1476737775","violations":[{"violationId":"8df2499ea280a7f8de25047c433f5aaff2d13b34eef249caea92dce2a1b4d9a5","modelName":null,"category":"INVALID_VALUE","severity":"MINOR","violationType":"Rule","validationRule":"heat-stack-id equals first 11 bytes of vnf-name","violationDetails":{"heat-stack-id":null,"vnf-name":"mtjnj484vbc"},"errorMessage":"Invalid value - the value of heat-stack-id must equal the first 11 bytes of vnf-name"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-name.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-name.exp.json new file mode 100644 index 0000000..2fa2f4c --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-name.exp.json @@ -0,0 +1 @@ +{"validationId":"c9757c6c-1168-4da7-8bd9-580e530cb964","validationTimestamp":"20170104T181242Z","entityId":{"hostname":"gdrmi101sd9"},"entityType":"pserver","entityLink":"https://inventory/v8/cloud-infrastructure/pservers/pserver/example-vserver-id-val-34666","resourceVersion":"1478050351","violations":[{"violationId":"4e2fcd58dfcf9d8305c7a5368926a57325971eac2972ca563c3c5fd142847ab4","modelName":null,"category":"INVALID_VALUE","severity":"MINOR","violationType":"Rule","validationRule":"pserver.name","violationDetails":{"ptnii-equip-name":"gdrmi101sd9.infra.aic.att.net"},"errorMessage":"Invalid value - field must not contain .infra.aic.att.net"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-type.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-type.exp.json new file mode 100644 index 0000000..132cd55 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-bad-equip-type.exp.json @@ -0,0 +1 @@ +{"validationId":"f9182835-eb6b-421b-a1db-0944f89d9319","validationTimestamp":"20170104T174235Z","entityId":{"hostname":"gdrmi101sd9"},"entityType":"pserver","entityLink":"https://inventory/v8/cloud-infrastructure/pservers/pserver/example-vserver-id-val-34666","resourceVersion":"1478050351","violations":[{"violationId":"3fab89215ebdc75e029c4c50c20d9cf050d92c234cd94bc630fc14fff7c8934d","modelName":null,"category":"INVALID_VALUE","severity":"MINOR","violationType":"Rule","validationRule":"equip-type","violationDetails":{"equip-type":"toa"},"errorMessage":"Invalid value - attribute must not have a value of toa or hitachi"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-good.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-good.exp.json new file mode 100644 index 0000000..0882b0d --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-good.exp.json @@ -0,0 +1 @@ +{"validationId":"24c57a3f-4796-496f-825f-d609e2191ad1","validationTimestamp":"20170104T174428Z","entityId":{"hostname":"gdrmi101sd9"},"entityType":"pserver","entityLink":"https://inventory/v8/cloud-infrastructure/pservers/pserver/example-vserver-id-val-34666","resourceVersion":"1478050351","violations":[]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status-missing.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status-missing.exp.json new file mode 100644 index 0000000..a4bddd3 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status-missing.exp.json @@ -0,0 +1,121 @@ +{ + "validationId": "6e169924-9611-4db4-b117-3d9d266270ab", + "validationTimestamp": "20180416T102312Z", + "entityId": { + "hostname": "gdrmi101sd9" + }, + "entityType": "pserver", + "entityLink": "https://inventory/v8/cloud-infrastructure/pservers/pserver/example-vserver-id-val-34666", + "resourceVersion": "1478050351", + "entity": { + "hostname": "gdrmi101sd9", + "ptnii-equip-name": "gdrmi101sd9", + "equip-type": "server", + "equip-vendor": "HP", + "equip-model": "DL380p9-nd", + "fqdn": "gdrmirsv101.gdrmi.sbcglobal.net", + "ipv4-oam-address": "12.80.20.75", + "in-maint": false, + "resource-version": "1478050351", + "purpose": "LCP", + "relationship-list": { + "relationship": [ + { + "related-to": "complex", + "related-link": "https://inventory/v8/cloud-infrastructure/complexes/complex/GDRPMIBL/", + "relationship-data": [ + { + "relationship-key": "complex.physical-location-id", + "relationship-value": "GDRPMIBL" + } + ] + } + ] + }, + "p-interfaces": { + "p-interface": [ + { + "interface-name": "p4p1-4/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051189", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p1-4%2F1%7Cgdrmitax101%3Axe-0%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p1-4/1|gdrmitax101:xe-0/0/1" + } + ] + } + ] + } + }, + { + "interface-name": "p4p2-4/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051190", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p2-4%2F2%7Cgdrmitax101%3Axe-0%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p2-4/2|gdrmitax101:xe-0/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p1-6/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051200", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p1-6%2F1%7Cgdrmitax102%3Axe-1%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p1-6/1|gdrmitax102:xe-1/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p2-6/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051199", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p2-6%2F2%7Cgdrmitax102%3Axe-1%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p2-6/2|gdrmitax102:xe-1/0/1" + } + ] + } + ] + } + } + ] + } + }, + "violations": [] +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status.exp.json new file mode 100644 index 0000000..2574a88 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/pserver/pserver-create-AAI-EVENT-devINT1-inv-status.exp.json @@ -0,0 +1,135 @@ +{ + "validationId": "5e42e954-f342-4a69-b011-c01ad2c759aa", + "validationTimestamp": "20180416T103958Z", + "entityId": { + "hostname": "gdrmi101sd9" + }, + "entityType": "pserver", + "entityLink": "https://inventory/v8/cloud-infrastructure/pservers/pserver/example-vserver-id-val-34666", + "resourceVersion": "1478050351", + "entity": { + "hostname": "gdrmi101sd9", + "ptnii-equip-name": "gdrmi101sd9", + "equip-type": "server", + "equip-vendor": "HP", + "equip-model": "DL380p9-nd", + "fqdn": "gdrmirsv101.gdrmi.sbcglobal.net", + "ipv4-oam-address": "12.80.20.75", + "in-maint": false, + "resource-version": "1478050351", + "purpose": "LCP", + "inv-status": "Incorrect status value", + "relationship-list": { + "relationship": [ + { + "related-to": "complex", + "related-link": "https://inventory/v8/cloud-infrastructure/complexes/complex/GDRPMIBL/", + "relationship-data": [ + { + "relationship-key": "complex.physical-location-id", + "relationship-value": "GDRPMIBL" + } + ] + } + ] + }, + "p-interfaces": { + "p-interface": [ + { + "interface-name": "p4p1-4/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051189", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p1-4%2F1%7Cgdrmitax101%3Axe-0%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p1-4/1|gdrmitax101:xe-0/0/1" + } + ] + } + ] + } + }, + { + "interface-name": "p4p2-4/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051190", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap4p2-4%2F2%7Cgdrmitax101%3Axe-0%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p4p2-4/2|gdrmitax101:xe-0/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p1-6/1", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051200", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p1-6%2F1%7Cgdrmitax102%3Axe-1%2F0%2F51/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p1-6/1|gdrmitax102:xe-1/0/51" + } + ] + } + ] + } + }, + { + "interface-name": "p6p2-6/2", + "speed-value": "10000000", + "speed-units": "kbps", + "resource-version": "1478051199", + "relationship-list": { + "relationship": [ + { + "related-to": "physical-link", + "related-link": "https://inventory/v8/network/physical-links/physical-link/gdrmi101sd9%3Ap6p2-6%2F2%7Cgdrmitax102%3Axe-1%2F0%2F1/", + "relationship-data": [ + { + "relationship-key": "physical-link.link-name", + "relationship-value": "gdrmi101sd9:p6p2-6/2|gdrmitax102:xe-1/0/1" + } + ] + } + ] + } + } + ] + } + }, + "violations": [ + { + "violationId": "e5c746b4b5eafa608644e3d191136eea0e31906e36ffd9f9fcd8e3ea466b27ad", + "modelName": null, + "category": "INVALID_VALUE", + "severity": "CRITICAL", + "violationType": "Rule", + "validationRule": "pserver inv-status attribute allowed values", + "violationDetails": { + "inv-status": "Incorrect status value" + }, + "errorMessage": "Invalid inv-status value. Must be Deployed, In Service, Not Specified, Pending Delete, Planned, Planned Modify" + } + ] +} \ No newline at end of file diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vf-module/vf-module-delete-AAI-EVENT-devINT1.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vf-module/vf-module-delete-AAI-EVENT-devINT1.error new file mode 100644 index 0000000..cfef9b8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vf-module/vf-module-delete-AAI-EVENT-devINT1.error @@ -0,0 +1 @@ +No validation results available. The action value may have caused the event to be filtered. Otherwise the event type or domain may be invalid. diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vf-module/vf-module-delete-AAI-EVENT-e2e1.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vf-module/vf-module-delete-AAI-EVENT-e2e1.error new file mode 100644 index 0000000..cfef9b8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vf-module/vf-module-delete-AAI-EVENT-e2e1.error @@ -0,0 +1 @@ +No validation results available. The action value may have caused the event to be filtered. Otherwise the event type or domain may be invalid. diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vf-module/vf-module-delete-AAI-RUBBISH-devINT1.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vf-module/vf-module-delete-AAI-RUBBISH-devINT1.error new file mode 100644 index 0000000..cfef9b8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vf-module/vf-module-delete-AAI-RUBBISH-devINT1.error @@ -0,0 +1 @@ +No validation results available. The action value may have caused the event to be filtered. Otherwise the event type or domain may be invalid. diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vnf-image/vnf-image-create-AAI-EVENT-devINT1.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/vnf-image/vnf-image-create-AAI-EVENT-devINT1.exp.json new file mode 100644 index 0000000..24cca5c --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vnf-image/vnf-image-create-AAI-EVENT-devINT1.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"att-uuid":"750c29ff-12cb-4be5-88bc-648f27748113"},"entityType":"vnf-image","entityLink":"service-design-and-creation/vnf-images/vnf-image/750c29ff-12cb-4be5-88bc-648f27748113","resourceVersion":"1476735375","violations":[]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-BAD.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-BAD.exp.json new file mode 100644 index 0000000..ad30920 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-BAD.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"vserver-id":"c385bb3e-6ebd-4898-bc92-792e0ac2db50"},"entityType":"vserver","entityLink":"cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666","resourceVersion":"1475160142","violations":[{"violationId":"4e100c3055f1a03608adc655bf1ece9c26a2eeda7a58d652689be52535626f36","modelName":null,"category":"INVALID_NAME","severity":"MINOR","violationType":"Rule","validationRule":"vserver related to TRINITY image and generic-vnf.vnf-name matches naming convention","violationDetails":{"relationship-list.relationship[*]":[{"related-to":"generic-vnf","related-link":"https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx12345v/","relationship-data":[{"relationship-key":"generic-vnf.vnf-id","relationship-value":"ctpx12345v"}],"related-to-property":[{"property-key":"generic-vnf.vnf-name","property-value":"ctpx12345v"}]},{"related-to":"vf-module","related-link":"https://135.16.121.249:8443/aai/v8/network/generic-vnfs/generic-vnf/ctpx12345v/vf-modules/vf-module/ctpx12345v/","relationship-data":[{"relationship-key":"generic-vnf.vnf-id","relationship-value":"ctpx12345v"},{"relationship-key":"vf-module.vf-module-id","relationship-value":"ctpx12345v"}]},{"related-to":"image","related-link":"https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/images/image/TRINITY-IMAGE/","relationship-data":[{"relationship-key":"cloud-region.cloud-owner","relationship-value":"att-aic"},{"relationship-key":"cloud-region.cloud-region-id","relationship-value":"AAIAIC25"},{"relationship-key":"image.image-id","relationship-value":"TRINITY-IMAGE"}],"related-to-property":[{"property-key":"image.image-name","property-value":"TRINITY IMAGE"}]},{"related-to":"pserver","related-link":"https://135.16.121.249:8443/aai/v8/cloud-infrastructure/pservers/pserver/TRINITY-PSERVER/","relationship-data":[{"relationship-key":"pserver.hostname","relationship-value":"TRINITY-PSERVER"}],"related-to-property":[{"property-key":"pserver.pserver-name2"}]},{"related-to":"flavor","related-link":"https://135.16.121.249:8443/aai/v8/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/flavors/flavor/TRINITY-Flavor/","relationship-data":[{"relationship-key":"cloud-region.cloud-owner","relationship-value":"att-aic"},{"relationship-key":"cloud-region.cloud-region-id","relationship-value":"AAIAIC25"},{"relationship-key":"flavor.flavor-id","relationship-value":"TRINITY-Flavor"}],"related-to-property":[{"property-key":"flavor.flavor-name","property-value":"TRINITY Flavor"}]}]},"errorMessage":"Invalid name - if vserver is related to an image named TRINITY, then the related generic-vnf name must match xxxxnnnnv (where x = character and n = number)"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-GOOD.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-GOOD.exp.json new file mode 100644 index 0000000..98ddc4c --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-TRINITY-VNF-NAME-GOOD.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"vserver-id":"c385bb3e-6ebd-4898-bc92-792e0ac2db50"},"entityType":"vserver","entityLink":"cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666","resourceVersion":"1475160142","violations":[]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-malformed-JSON.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-malformed-JSON.error new file mode 100644 index 0000000..cc83d43 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-malformed-JSON.error @@ -0,0 +1 @@ +VS-500, JSON could not be parsed.; Caused by: com.google.gson.stream.MalformedJsonException: Unterminated object at line 151 column 7 path $.entity.tenants.tenant[0].vservers diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-two-vserver-objects.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-two-vserver-objects.error new file mode 100644 index 0000000..c5bc463 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1-two-vserver-objects.error @@ -0,0 +1 @@ +VS-502, Unexpected number or entities. diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1.exp.json new file mode 100644 index 0000000..bf56436 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-devINT1.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"vserver-id":"example-vserver-id-val-34666"},"entityType":"vserver","entityLink":"cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/example-tenant-id-val-88551/vservers/vserver/example-vserver-id-val-34666","resourceVersion":"1464193654","violations":[{"violationId":"9f2d9ee595e1390ec0ffe60cea0b620a23ee9a84b6b6fb241ed84bf784b92393","modelName":null,"category":"MISSING_REL","severity":"MINOR","violationType":"Rule","validationRule":"vserver is related to 1 pserver","violationDetails":{"relationship-list.relationship[*].related-to":[]},"errorMessage":"Missing relationship - vserver must be related to 1 pserver"},{"violationId":"cbc9b9fe5b40de9814e128173b6d25a77e37b8e4c36ce47c5582807505a2e7dc","modelName":null,"category":"MISSING_REL","severity":"MINOR","violationType":"Rule","validationRule":"vserver is related to a vnf (vce or newvce or vpe or generic-vnf)","violationDetails":{"relationship-list.relationship[*].related-to":[]},"errorMessage":"Missing relationship - a vserver must be related to a vnf (vce or newvce or vpe or generic-vnf)"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-e2e1.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-e2e1.error new file mode 100644 index 0000000..cfef9b8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-EVENT-e2e1.error @@ -0,0 +1 @@ +No validation results available. The action value may have caused the event to be filtered. Otherwise the event type or domain may be invalid. diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-INVALID-devINT1.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-INVALID-devINT1.error new file mode 100644 index 0000000..cfef9b8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-create-AAI-INVALID-devINT1.error @@ -0,0 +1 @@ +No validation results available. The action value may have caused the event to be filtered. Otherwise the event type or domain may be invalid. diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-delete-AAI-BAD123-devINT1.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-delete-AAI-BAD123-devINT1.error new file mode 100644 index 0000000..cfef9b8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-delete-AAI-BAD123-devINT1.error @@ -0,0 +1 @@ +No validation results available. The action value may have caused the event to be filtered. Otherwise the event type or domain may be invalid. diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-devINT1.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-devINT1.error new file mode 100644 index 0000000..cfef9b8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-devINT1.error @@ -0,0 +1 @@ +No validation results available. The action value may have caused the event to be filtered. Otherwise the event type or domain may be invalid. diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-e2e1.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-e2e1.error new file mode 100644 index 0000000..cfef9b8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-delete-AAI-EVENT-e2e1.error @@ -0,0 +1 @@ +No validation results available. The action value may have caused the event to be filtered. Otherwise the event type or domain may be invalid. diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-update-AAI-EVENT-devINT1.exp.json b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-update-AAI-EVENT-devINT1.exp.json new file mode 100644 index 0000000..f6cfbcf --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-update-AAI-EVENT-devINT1.exp.json @@ -0,0 +1 @@ +{"validationId":"VALIDATIONID","validationTimestamp":"TIMESTAMP","entityId":{"vserver-id":"fd280243-cd5c-424e-b629-533cabe2a164"},"entityType":"vserver","entityLink":"cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/d52b9dea5d0f4e5d90be3590ac8c78a9/vservers/vserver/fd280243-cd5c-424e-b629-533cabe2a164","resourceVersion":"1476735222","violations":[{"violationId":"6db365a3ed9c3e0aa94434b2607ae9ddab45153f1eb9ed0b312c1297d92c621b","modelName":null,"category":"MISSING_REL","severity":"MINOR","violationType":"Rule","validationRule":"vserver is related to a vnf (vce or newvce or vpe or generic-vnf)","violationDetails":{"relationship-list.relationship[*].related-to":["image","pserver","flavor"]},"errorMessage":"Missing relationship - a vserver must be related to a vnf (vce or newvce or vpe or generic-vnf)"}]} diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-update-AAI-EVENT-testINT1.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-update-AAI-EVENT-testINT1.error new file mode 100644 index 0000000..cfef9b8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-update-AAI-EVENT-testINT1.error @@ -0,0 +1 @@ +No validation results available. The action value may have caused the event to be filtered. Otherwise the event type or domain may be invalid. diff --git a/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-update-AAI-TEST9-devINT1.error b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-update-AAI-TEST9-devINT1.error new file mode 100644 index 0000000..cfef9b8 --- /dev/null +++ b/src/integration-test/resources/system_test/results/expected/rule-driven/vserver-tests/vserver-update-AAI-TEST9-devINT1.error @@ -0,0 +1 @@ +No validation results available. The action value may have caused the event to be filtered. Otherwise the event type or domain may be invalid. diff --git a/src/integration-test/resources/system_test/testRunner/DARE.conf b/src/integration-test/resources/system_test/testRunner/DARE.conf new file mode 100644 index 0000000..779cafd --- /dev/null +++ b/src/integration-test/resources/system_test/testRunner/DARE.conf @@ -0,0 +1,25 @@ +#!/bin/bash +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END===================================================== + +export TOPIC_HOST="http://uebsb91kcdc.it.att.com:3904,http://uebsb92kcdc.it.att.com:3904,http://uebsb93kcdc.it.att.com:3904" +export TOPIC_INPUT="AAI-DATA-EXPORT-DEV" +export TOPIC_OUTPUT="AAI-DATA-INTEGRITY-DEV" +export TOPIC_CGROUP="CG3" +export TOPIC_CID="id1" +export TOPIC_PARTITION="1" +export TOPIC_API_USERNAME="wSJBo7eYbYSeUjrR" +export TOPIC_API_PASSWORD="S8iKAcFoFf7S3eaxqZer2ZVY" diff --git a/src/integration-test/resources/system_test/testRunner/DIMO.conf b/src/integration-test/resources/system_test/testRunner/DIMO.conf new file mode 100644 index 0000000..779cafd --- /dev/null +++ b/src/integration-test/resources/system_test/testRunner/DIMO.conf @@ -0,0 +1,25 @@ +#!/bin/bash +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END===================================================== + +export TOPIC_HOST="http://uebsb91kcdc.it.att.com:3904,http://uebsb92kcdc.it.att.com:3904,http://uebsb93kcdc.it.att.com:3904" +export TOPIC_INPUT="AAI-DATA-EXPORT-DEV" +export TOPIC_OUTPUT="AAI-DATA-INTEGRITY-DEV" +export TOPIC_CGROUP="CG3" +export TOPIC_CID="id1" +export TOPIC_PARTITION="1" +export TOPIC_API_USERNAME="wSJBo7eYbYSeUjrR" +export TOPIC_API_PASSWORD="S8iKAcFoFf7S3eaxqZer2ZVY" diff --git a/src/integration-test/resources/system_test/testRunner/default.conf b/src/integration-test/resources/system_test/testRunner/default.conf new file mode 100644 index 0000000..8ba4e46 --- /dev/null +++ b/src/integration-test/resources/system_test/testRunner/default.conf @@ -0,0 +1,48 @@ +#!/bin/bash +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +# set JAVA Home +export JAVA_HOME=/usr/java/latest +export PATH=${JAVA_HOME}/bin:${PATH} + +# application server +export APP_SERVER=devINT1 + +# validation-service +export VS_HOME=/opt/app/validation-service +export VS_CONF=${VS_HOME}/conf +export VS_LOGS=${VS_HOME}/logs +export VS_BIN=${VS_HOME}/bin +export VS_LOGBK=${VS_HOME}/bundleconfig/etc +export TOPIC_LOGS=${VS_BIN}/logs + +# gap-service +export GS_HOME=/opt/app/gap-service +export GS_CONF=${GS_HOME}/conf +export GS_LOGS=${GS_HOME}/logs +export GS_BIN=${GS_HOME}/bin +export GS_LOGBK=${GS_HOME}/bundleconfig/etc + +# test harness +export SYSTEM_TEST=${HOME}/system_test +export RUNNER=${SYSTEM_TEST}/testRunner +export DATA=${SYSTEM_TEST}/data +export RULE=${SYSTEM_TEST}/rules +export GAP=${SYSTEM_TEST}/gap +export RESULTS=${SYSTEM_TEST}/results +export ACTUAL=${RESULTS}/actual +export EXPECTED=${RESULTS}/expected diff --git a/src/integration-test/resources/system_test/testRunner/runDareTests.sh b/src/integration-test/resources/system_test/testRunner/runDareTests.sh new file mode 100644 index 0000000..0037a45 --- /dev/null +++ b/src/integration-test/resources/system_test/testRunner/runDareTests.sh @@ -0,0 +1,310 @@ +#!/bin/bash +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +source default.conf +source ${RUNNER}/DARE.conf + +function topic_consume +{ + local topic=$1 + local msg_count=0 + local msg_total=0 + + echo "INFO: Function topic_consume called with topic=$topic" + + while true + do + if [ -e ${TOPIC_LOGS}/application.log ]; then + #echo "INFO: Remove ${TOPIC_LOGS}/application.log" + rm ${TOPIC_LOGS}/application.log + else + echo "INFO: ${TOPIC_LOGS}/application.log does not exist" + fi + ${VS_BIN}/event-consumer.sh $TOPIC_HOST $topic $TOPIC_CGROUP $TOPIC_CID $TOPIC_API_USERNAME $TOPIC_API_PASSWORD > /dev/null 2> /dev/null + cp ${TOPIC_LOGS}/application.log ${RUNNER}/${topic}-app.log + +# msg_count=$(grep "cambria.partition" ${RUNNER}/${topic}-app.log | wc -l) + msg_count=$(grep -e '"event-header":{"event-type"' -e '{"validationId"' ${RUNNER}/${topic}-app.log | wc -l) + echo "INFO: msg_count = $msg_count" + if [ ${msg_count} == "0" ]; then + echo "INFO: No more messages on topic $topic" + break + fi + done + + return 0 +} + + +# +# runDareTests.sh - script starts here +# + + +testtotal=0 +testcount=0 +passes=0 +fails=0 +skips=0 +lrmOutput="" +ecount=0 +verbose="false" + +# colour terminal escape sequences +PASS="\e[32mPASS\e[39m" +FAIL="\e[31mFAIL\e[39m" +SKIP="\e[33mSKIP\e[39m" +TEST="\e[33mTEST\e[39m" +GREEN_ON="\e[32m" +BLUE_ON="\e[36m" +YELLOW_ON="\e[93m" +COLOUR_OFF="\e[39m" + + +# check command line arguments +if [ $# -gt 1 ]; then + echo "Too many arguments: $*" + echo "Usage: $0 [-verbose]" + exit 1 +fi + +# output message contents in verbose mode +if [[ $# == 1 ]]; then + if [[ $1 == "-verbose" ]]; then + verbose="true" + else + echo echo "Unrecognised argument: $1" + echo "Usage: $0 [-verbose]" + exit 1 + fi +fi + + +# remove the GAP service application.log to start from a clean log +if [ -e ${GS_LOGS}/application.log ]; then + echo "INFO: removing ${GS_LOGS}/application.log" + rm ${GS_LOGS}/application.log +fi + + +# remove the Validation service application.log to start from a clean log +if [ -e ${VS_LOGS}/application.log ]; then + echo "INFO: removing ${VS_LOGS}/application.log" + rm ${VS_LOGS}/application.log +fi + + +# set DEBUG log level if VS or GS logback.xml is currently INFO level +sed -i "s/root level=\"INFO\"/root level=\"DEBUG\"/" ${GS_LOGBK}/logback.xml +sed -i "s/root level=\"INFO\"/root level=\"DEBUG\"/" ${VS_LOGBK}/logback.xml + + +# restart the GAP microservice +echo "INFO: restarting the GAP Service for APP_SERVER=${APP_SERVER}" +/opt/app/swm/scldlrm/bin/lrmcli -bounce -name com.att.ajsc.gap-service -version 1.0.1 -routeoffer ${APP_SERVER} + +# restart the Validation microservice +echo "INFO: restarting the Validation Service for APP_SERVER=${APP_SERVER}" +/opt/app/swm/scldlrm/bin/lrmcli -bounce -name com.att.ajsc.validation-service -version 1.0.1 -routeoffer ${APP_SERVER} + +sleep 5 + +# exit if the gap-service or validation-service is not running +for service in gap-service validation-service +do + lrmOutput=$(/opt/app/swm/scldlrm/bin/lrmcli -running | grep "com.att.ajsc.${service}" | grep -e "HEARTBEAT,COMPLETED_SUCCESSFULLY" -e "START,COMPLETED_SUCCESSFULLY") + if [ $? != 0 ]; then + echo -e "${FAIL}: exit - the ${service} is not running" + exit 1 + fi + echo -e "INFO: ${lrmOutput}" +done + + +# cd to Validation Service HOME so that TOPIC logs are written to $VS_BIN/logs/application.log +cd ${VS_BIN} +if [ $? != 0 ]; then + echo -e "${FAIL}: exit - unable to cd to ${VS_BIN}" + exit 1 +fi + + +# exit if consumer/publisher scripts are not present or not executable +if [[ ! -x ${VS_BIN}/event-consumer.sh || ! -x ${VS_BIN}/event-publisher.sh ]]; then + echo -e "${FAIL}: exit - consumer/publisher scripts are not present or not executable" + exit 1 +fi + +#echo "INFO: Clear the INPUT event queue" +topic_consume ${TOPIC_INPUT} + +#echo "INFO: Clear the OUTPUT event queue" +topic_consume ${TOPIC_OUTPUT} + +#echo "INFO: Clear ${ACTUAL}" +#rm -rf ${ACTUAL} +#mkdir ${ACTUAL} + +# exit if the gap directory does not exist +if [[ ! -d ${GAP} ]]; then + echo "ERROR: gap directory not found: $GAP" + exit 1 +fi + +########################################### +#sleep 20 +########################################### + +# execute the gap-client.py python script to trigger a DARE request +SECONDS=0 +duration=0 +echo "INFO: "`date +"%F %T"` "GAP POST request STARTED" +echo "INFO: source ${GS_BIN}/gap-client.sh; python ${GS_BIN}/gap-client.py $GAP" +source ${GS_BIN}/gap-client.sh; python ${GS_BIN}/gap-client.py $GAP > ${RUNNER}/gap-req.log 2>&1 + +echo "INFO: "`date +"%F %T"` "GAP POST request FINISHED" + +# output elapsed time +duration=$SECONDS +echo -e ${BLUE_ON}"INFO: GAP request took $(($duration / 3600)) hours $(($duration / 60)) minutes and $(($duration % 60)) seconds to complete"${COLOUR_OFF} + +# display the output from gap-client.py as INFO +while read gline +do + echo "INFO: $gline" +done < ${RUNNER}/gap-req.log + + +# verfiy the request completed successfully +grep "Request processed successfully" ${RUNNER}/gap-req.log > /dev/null 2>&1 +if [ $? != 0 ]; then + echo -e "${FAIL}: exit - the DARE request was not successful" + exit 1 +fi + +# gap-client.py has completed so all entites should have been returned from the AAI +# use sed to extract all AAI entities from the GAP log and save them to entity.log +grep "Retrieved payload from rest client. Payload :" ${GS_LOGS}/application.log | sed -e "s/\([^{]*\)\([^|]*\).*/\2/" > ${RUNNER}/entity.log 2>&1 +if [ $? != 0 ]; then + echo -e "${FAIL}: exit - no Retrieved entities found in ${GS_LOGS}/application.log" + exit 1 +fi + +# display each entity retrieved from the AAI as INFO if verbose=true +if [ ${verbose} == "true" ]; then + while read eline; do + echo "INFO: $eline" + done < ${RUNNER}/entity.log +fi + +# count how many entities have been retrieved from the AAI +ecount=$(wc -l ${RUNNER}/entity.log | cut -d" " -f1) +echo -e "INFO: ${BLUE_ON}Number of objects retrieved from the A&AI = $ecount"${COLOUR_OFF} + +# +# count how many events GAP publishes to the topic for the validation service to consume +# + +gap_curr=0 +gap_prev=0 +gap_retry=0 +while [ $gap_retry -lt 3 ] +do +# sleep 1 + gap_curr=$(grep --line-buffered -i -e '"event-type":"AAI-DATA-EXPORT-API"' -e '"event-type":"AAI-DATA-EXPORT-NQ"' /opt/app/gap-service/logs/application.log | wc -l) + if [ $gap_curr -gt $gap_prev ]; then + echo "INFO: GAP Service events published = $gap_curr" + gap_prev=$gap_curr + gap_retry=0 + continue + else + if [ $gap_curr -lt $gap_prev ]; then + echo "INFO: gap_curr = $gap_curr" + echo "INFO: gap_prev = $gap_prev" + echo -e "${FAIL}: exit - gap_curr should never be less than gap_prev" + exit 1 + fi + if [ $gap_curr -eq $gap_prev ]; then + let gap_retry+=1 + echo "INFO: GAP retry counter = $gap_retry" + echo "INFO: GAP Service events published = $gap_curr" + sleep 10 + continue + fi + fi +done + +# gap_curr should equal ecount +echo -e "INFO: ${BLUE_ON}Number of events published by GAP = $gap_curr"${COLOUR_OFF} +#echo "INFO: number of objects retrieved from the A&AI = $ecount" +if [ $gap_curr -eq $ecount ]; then + echo -e "${PASS}: ${GREEN_ON}number of events published by GAP matches the number of objects retrieved from the A&AI"${COLOUR_OFF} +else + echo -e "${FAIL}: number of events published by GAP does not match the number of objects retrieved from the A&AI" +fi + + +# +# count how many validation payloads the validation service publishes to the topic for the DI UI to consume +# + +vs_curr=0 +vs_prev=0 +vs_retry=0 +while [ $vs_retry -lt 3 ] +do +# sleep 1 + vs_curr=$(grep --line-buffered -i -e "validationid" /opt/app/validation-service/logs/application.log | wc -l) + if [ $vs_curr -gt $vs_prev ]; then + echo "INFO: Validation Service events published = $vs_curr" + vs_prev=$vs_curr + vs_retry=0 + continue + else + if [ $vs_curr -lt $vs_prev ]; then + echo "INFO: vs_curr = $vs_curr" + echo "INFO: vs_prev = $vs_prev" + echo -e "${FAIL}: exit - vs_curr should never be less than vs_prev" + exit 1 + fi + if [ $vs_curr -eq $vs_prev ]; then + let vs_retry+=1 + echo "INFO: Validation retry counter = $vs_retry" + echo "INFO: Validation Service payloads published = $vs_curr" + sleep 10 + continue + fi + fi +done + +# output a timestamp when the validation service has finished publishing payloads +echo -e "INFO: "`date +"%F %T"` "Validation Service has FINISHED publishing validation payloads" + +# vs_curr should equal ecount +echo -e "INFO: ${BLUE_ON}Number of validation payloads published by the validation service = $vs_curr"${COLOUR_OFF} +#echo "INFO: number of objects retrieved from the A&AI = $ecount" +if [ $vs_curr -eq $ecount ]; then + echo -e "${PASS}: ${GREEN_ON}number of events published by the validation service matches the number of objects retrieved from the A&AI"${COLOUR_OFF} +else + echo -e "${FAIL}: number of events published by the validation service does not match the number of objects retrieved from the A&AI" +fi + +# output elapsed time +duration=$SECONDS +echo -e "INFO: ${BLUE_ON}Total E2E test execution took $(($duration / 3600)) hours $(($duration / 60)) minutes and $(($duration % 60)) seconds to complete"${COLOUR_OFF} + + diff --git a/src/integration-test/resources/system_test/testRunner/runDimoTests.sh b/src/integration-test/resources/system_test/testRunner/runDimoTests.sh new file mode 100644 index 0000000..efe241c --- /dev/null +++ b/src/integration-test/resources/system_test/testRunner/runDimoTests.sh @@ -0,0 +1,346 @@ +#!/bin/bash +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +source default.conf +source ${RUNNER}/DIMO.conf + +function topic_consume +{ + local topic=$1 + local msg_count=0 + local msg_total=0 + + echo "INFO: Function topic_consume called with topic=$topic" + + while true + do + if [ -e ${TOPIC_LOGS}/application.log ]; then + #echo "INFO: Remove ${TOPIC_LOGS}/application.log" + rm ${TOPIC_LOGS}/application.log + else + echo "INFO: ${TOPIC_LOGS}/application.log does not exist" + fi + ${VS_BIN}/event-consumer.sh $TOPIC_HOST $topic $TOPIC_CGROUP $TOPIC_CID $TOPIC_API_USERNAME $TOPIC_API_PASSWORD > /dev/null 2> /dev/null + cp ${TOPIC_LOGS}/application.log ${RUNNER}/${topic}-app.log + + msg_count=$(grep "cambria.partition" ${RUNNER}/${topic}-app.log | wc -l) + echo "INFO: msg_count = $msg_count" + if [ ${msg_count} == "0" ]; then + echo "INFO: No more messages on topic $topic" + break + fi + done + + return 0 +} + +function topic_consume_and_extract_json +{ + local topic=$1 + local json_input=$2 + local actual=$3 + +# echo "INFO: Function topic_consume_and_extract_json called with topic=$topic and json_input=$json_input and actual directory=$actual" +# echo "INFO: Remove ${TOPIC_LOGS}/application.log" + + # need a clean log so rm existing log file + rm ${TOPIC_LOGS}/application.log + + # consumed TOPIC event(s) will be written to a newly created application.log + ${VS_BIN}/event-consumer.sh $TOPIC_HOST $topic $TOPIC_CGROUP $TOPIC_CID $TOPIC_API_USERNAME $TOPIC_API_PASSWORD > /dev/null 2> /dev/null + + # take a local copy of the application.log + cp ${TOPIC_LOGS}/application.log ${RUNNER}/topic_json.log + +# sed -e '/ - url :/d' \ +# -e '/ - topic :/d' \ +# -e '/ - partition :/d' \ +# -e '/ - message :/d' \ +# -e '/ - username :/d' \ +# -e '/ - password :/d' \ +# -e '/c.att.nsa.apiClient.http.HttpClient/d' \ +# -e '/com.att.nsa.cambria.client.impl.CambriaConsumerImpl/d' \ +# -e '/c.a.n.c.c.impl.CambriaConsumerImpl/d' \ +# -e '/Count of messages consumed/d' \ +# -e 's/.*com.att.ecomp.event.client.test.TestEventConsumer - //g' ${RUNNER}/topic_json.log > ${actual}/${json_input}.raw.json + + sed -e '/ - | url :/d' \ + -e '/ - | topic :/d' \ + -e '/ - | consumerGroup :/d' \ + -e '/ - | consumerId :/d' \ + -e '/ - | username :/d' \ + -e '/ - | password :/d' \ + -e '/c.att.nsa.apiClient.http.HttpClient/d' \ + -e '/com.att.nsa.cambria.client.impl.CambriaConsumerImpl/d' \ + -e '/c.a.n.c.c.impl.CambriaConsumerImpl/d' \ + -e '/Count of messages consumed/d' \ + -e 's/.*com.att.ecomp.event.client.test.TestEventConsumer - | //g' \ + -e 's/\(.*\)\(|\)/\1/g' ${RUNNER}/topic_json.log > ${actual}/${json_input}.raw.json + + # mask out variable information such as the unique identifier, the timestamp and the entityLink + # Note: don't use the global flag as we only want to replace first occurrence + sed -e 's/[a-z0-9]\{8\}-[a-z0-9]\{4\}-[a-z0-9]\{4\}-[a-z0-9]\{4\}-[a-z0-9]\{12\}/VALIDATIONID/' \ + -e 's/20[1-9][0-9][0-1][1-9][0-3][0-9]T[0-2][0-9][0-5][0-9][0-5][0-9]Z/TIMESTAMP/' ${actual}/${json_input}.raw.json > ${actual}/${json_input}.res.json + + return 0 +} + + +function topic_publish +{ + local topic=$1 + local json_file=$2 + + #echo "INFO: Function topic_publish called with topic=$topic and json_file=$json_file" + TOPIC_MESSAGE=$(cat ${json_file}) + ${VS_BIN}/event-publisher.sh "$TOPIC_HOST" "$topic" "$TOPIC_PARTITION" "$TOPIC_MESSAGE" "$TOPIC_API_USERNAME" "$TOPIC_API_PASSWORD" > /dev/null 2> /dev/null + +} + + +# +# runDimoTests.sh - script starts here +# + + +testtotal=0 +testcount=0 +passes=0 +fails=0 +skips=0 +lrmOutput="" +verbose="false" + +# colour terminal escape sequences +PASS="\e[32mPASS\e[39m" +FAIL="\e[31mFAIL\e[39m" +SKIP="\e[33mSKIP\e[39m" +TEST="\e[33mTEST\e[39m" +GREEN_ON="\e[32m" +BLUE_ON="\e[36m" +YELLOW_ON="\e[93m" +COLOUR_OFF="\e[39m" + + +# check command line arguments +if [ $# -gt 1 ]; then + echo "Too many arguments: $*" + echo "Usage: $0 [-verbose]" + exit 1 +fi + +# output message contents in verbose mode +if [[ $# == 1 ]]; then + if [[ $1 == "-verbose" ]]; then + verbose="true" + else + echo echo "Unrecognised argument: $1" + echo "Usage: $0 [-verbose]" + exit 1 + fi +fi + + +# cd to Validation Service BIN so that TOPIC logs are written to $VS_BIN/logs/application.log +cd ${VS_BIN} +if [ $? != 0 ]; then + echo -e "${FAIL}: exit - unable to cd to ${VS_BIN}" + exit 1 +fi + +# exit if the validation service is not running +lrmOutput=$(/opt/app/swm/scldlrm/bin/lrmcli -running | grep "com.att.ajsc.validation-service" | grep -e "HEARTBEAT,COMPLETED_SUCCESSFULLY" -e "START,COMPLETED_SUCCESSFULLY") +if [ $? != 0 ]; then + echo -e "${FAIL}: exit - the validation service is not running" + exit 1 +fi +echo -e "INFO: ${lrmOutput}" + +# exit if consumer/publisher scripts are not present or not executable +if [[ ! -x ${VS_BIN}/event-consumer.sh || ! -x ${VS_BIN}/event-publisher.sh ]]; then + echo -e "${FAIL}: exit - consumer/publisher scripts are not present or not executable" + exit 1 +fi + +#echo "INFO: Clear the INPUT event queue" +topic_consume ${TOPIC_INPUT} + +#echo "INFO: Clear the OUTPUT event queue" +topic_consume ${TOPIC_OUTPUT} + +#echo "INFO: Clear ${ACTUAL}" +rm -rf ${ACTUAL} +mkdir ${ACTUAL} + +# find test directories under $DATA +testdir=$(find ${DATA} -type d | sort | tail -n +2) +if [[ -z $testdir ]]; then + echo "ERROR: no test directories found under $DATA" + exit 1 +fi + +# find rule directories under $RULES +ruledir=$(find ${RULE} -type d | sort | tail -n +2) +if [[ -z $ruledir ]]; then + echo "ERROR: no rule directories found under $DATA" + exit 1 +fi + +# for each test directory under $DATA +for tdir in ${testdir}; do + + ls -l ${tdir}/*.json > /dev/null 2> /dev/null + if [ $? != 0 ]; then + echo "WARN: No JSON (input) files found in ${tdir} - skipping this dir" + continue + fi + tdir_name=$(basename $tdir) + + # for each config directory under $RULE + for rdir in ${ruledir}; do + + ls -l ${rdir}/*.groovy > /dev/null 2> /dev/null + if [ $? != 0 ]; then + echo "WARN: No Groovy (config) files found in ${rdir} - skipping this dir" + continue + fi + rdir_name=$(basename $rdir) + + echo "INFO: --------------------------------------------------------------------------------------" + echo "INFO: rule directory=$rdir_name" + echo "INFO: test directory=$tdir_name" + echo "INFO: --------------------------------------------------------------------------------------" + + # set actual and expected paths + actual=${ACTUAL}/${rdir_name}/${tdir_name} + expected=${EXPECTED}/${rdir_name}/${tdir_name} + + # create the actual result directory + # echo "INFO: mkdir -p ${actual}" + mkdir -p ${actual} + + # for each JSON file in $tdir + for json_file in ${tdir}/*.json ; do + + # loop through each test + testcount=$((testcount + 1)) + + json_filename=$(basename $json_file) + + # remove the extn - use rev so that f1 is the last field not the first field + json_input=$(echo $json_filename | rev | cut -d'.' --complement -s -f1 | rev) + + echo -e "${TEST}: ${YELLOW_ON}$json_input${COLOUR_OFF}" + + if [ $verbose == "true" ]; then + echo -e "INFO: ${BLUE_ON}JSON payload to be validated${COLOUR_OFF}" + cat ${tdir}/${json_filename} + fi + + # publish JSON payload to the INPUT topic + topic_publish ${TOPIC_INPUT} ${json_file} + + # wait for the validation service to send results to the TOPIC + # topic.consume.polling.interval.seconds=3 + # /opt/app/validation-service/etc/validation-service.properties + # echo "INFO: Sleeping for 10s" + sleep 15 + + # consume from the OUTPUT topic and save retrieved JSON to the actual results directory + topic_consume_and_extract_json ${TOPIC_OUTPUT} ${json_input} ${actual} + + # Skip the test if the expected results file does not exist + if [ ! -e ${expected}/${json_input}.exp.json -a ! -e ${expected}/${json_input}.error ]; then + echo -e "${SKIP}: no ${json_input}.exp.json or ${json_input}.error file found" + skips=$((skips + 1)) + continue + fi + + if [ -e ${expected}/${json_input}.error ]; then + # not expecting a vadatiion json payload on the output queue + if [ -s ${actual}/${json_input}.res.json ]; then + # test fails if a non-zero length results file exists + echo -e "${FAIL}: ${json_input}.json - unexpected validation message on the output queue" + fails=$((fails + 1)) + else + # test passes if a zero length results file exist + echo -e "${PASS}: ${json_input}.json - no validation message on the output queue as expected" + passes=$((passes + 1)) + fi + else + # a non-zero length result file is expected on the output queue + # Fail the test if the actual results file does not exist or is zero length + if [ ! -e ${actual}/${json_input}.res.json ]; then + echo -e "${FAIL}: ${json_input}.res.json - actual result file is missing" + fails=$((fails + 1)) + continue + else + if [ ! -s ${actual}/${json_input}.res.json ]; then + echo -e "${FAIL}: ${json_input}.res.json - actual result file is zero length (no JSON retrieved)" + fails=$((fails + 1)) + continue + fi + fi + + # compare the actual results against the expected results + diff --strip-trailing-cr ${expected}/${json_input}.exp.json ${actual}/${json_input}.res.json > ${actual}/${json_input}.diff + + diff_retval=$? + if [ "$diff_retval" == "0" ]; then + # actual and expected results match + # use python to format the json payload (raw output) + python -m json.tool ${actual}/${json_input}.raw.json > ${RUNNER}/pretty.json + if [ $verbose == "true" ]; then + # output the formatted validation payload + echo -e "INFO: ${BLUE_ON}validation result JSON payload${COLOUR_OFF}" + cat ${RUNNER}/pretty.json + echo -e "INFO: ${BLUE_ON}validation payload matches the expected result${COLOUR_OFF}" + fi + # report a test PASS status + echo -e "${PASS}: ${GREEN_ON}${json_input}.json${COLOUR_OFF}" + rm ${actual}/${json_input}.diff + passes=$((passes + 1)) + else + # actual and expected results do not match + fails=$((fails + 1)) + echo -e "${FAIL}: ${json_input}.json - the actual results do not match expected results" + while read diffline + do + echo "DIFF: $diffline" + done < ${actual}/${json_input}.diff + fi + fi + done + done +done + +# output the test summary statistics +echo "INFO: ====================" +echo "INFO: Test Results Summary" +echo "INFO: ====================" + +testtotal=$((passes + fails + skips)) +if [ $testtotal != $testcount ]; then + echo "ERROR: test statistics are inconsistent!" +fi + +echo "Total passes = $passes" +echo "Total failures = $fails" +echo "Total skipped tests = $skips" +echo "Total tests executed = $testtotal" + + diff --git a/src/integration-test/resources/system_test/testRunner/runVsRestTests.sh b/src/integration-test/resources/system_test/testRunner/runVsRestTests.sh new file mode 100644 index 0000000..314044a --- /dev/null +++ b/src/integration-test/resources/system_test/testRunner/runVsRestTests.sh @@ -0,0 +1,282 @@ +#!/bin/bash +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +source default.conf + +function post_json_payload +{ + local http_type=$1 + local json_file=$2 + local validation_service_url="" + + #echo "INFO: Function post_json_payload called with http_type=$http_type and json_file=$json_file" + case ${http_type} in + + http) + validation_service_url="http://localhost:9500/services/validation-service/v1/app/validate" + ;; + https) + validation_service_url="https://localhost:9501/services/validation-service/v1/app/validate" + ;; + *) + # should not get here + return 1 + ;; + esac + + # POST the JSON payload and save the JSON response as the actual result file (raw) + # Note: the --tlsv1.2 option is only relevant for SSL https connections, it will be ignored for http + curl --insecure -X POST -H "Content-Type:application/json" -H "Accept: application/json" \ + --tlsv1.2 -d @${json_file} ${validation_service_url} > ${actual}/${json_input}.raw.json 2> /dev/null + + # mask out variable information such as the unique identifier, the timestamp and the entityLink + # Note: don't use the global flag as we only want to replace first occurrence + sed -e 's/[a-z0-9]\{8\}-[a-z0-9]\{4\}-[a-z0-9]\{4\}-[a-z0-9]\{4\}-[a-z0-9]\{12\}/VALIDATIONID/' \ + -e 's/20[1-9][0-9][0-1][1-9][0-3][0-9]T[0-2][0-9][0-5][0-9][0-5][0-9]Z/TIMESTAMP/' ${actual}/${json_input}.raw.json > ${actual}/${json_input}.res.json + + # add a newline to the end of the file + echo "" >> ${actual}/${json_input}.res.json + + return 0 +} + + +# +# runVsRestTests.sh - script starts here +# + + +testtotal=0 +testcount=0 +passes=0 +fails=0 +skips=0 +lrmOutput="" +verbose="false" +vs_port=0 + +# colour terminal escape sequences +PASS="\e[32mPASS\e[39m" +FAIL="\e[31mFAIL\e[39m" +SKIP="\e[33mSKIP\e[39m" +TEST="\e[33mTEST\e[39m" +RED_ON="\e[31m" +GREEN_ON="\e[32m" +BLUE_ON="\e[36m" +YELLOW_ON="\e[93m" +COLOUR_OFF="\e[39m" + + +# check command line arguments +if [ $# -gt 1 ]; then + echo "Too many arguments: $*" + echo "Usage: $0 [-verbose]" + exit 1 +fi + +# output message contents in verbose mode +if [[ $# == 1 ]]; then + if [[ $1 == "-verbose" ]]; then + verbose="true" + else + echo echo "Unrecognised argument: $1" + echo "Usage: $0 [-verbose]" + exit 1 + fi +fi + +# exit if the validation service is not running +lrmOutput=$(/opt/app/swm/scldlrm/bin/lrmcli -running | grep "com.att.ajsc.validation-service" | grep -e "HEARTBEAT,COMPLETED_SUCCESSFULLY" -e "START,COMPLETED_SUCCESSFULLY") +if [ $? != 0 ]; then + echo -e "${FAIL}: exit - the validation service is not running" + exit 1 +fi +echo -e "INFO: ${lrmOutput}" + +#echo "INFO: Clear ${ACTUAL}" +rm -rf ${ACTUAL} +mkdir ${ACTUAL} + +# find test directories under $DATA +testdir=$(find ${DATA} -type d | sort | tail -n +2) +if [[ -z $testdir ]]; then + echo "ERROR: no test directories found under $DATA" + exit 1 +fi + +# find rule directories under $RULES +ruledir=$(find ${RULE} -type d | sort | tail -n +2) +if [[ -z $ruledir ]]; then + echo "ERROR: no rule directories found under $DATA" + exit 1 +fi + +# for each test directory under $DATA +for tdir in ${testdir}; do + + ls -l ${tdir}/*.json > /dev/null 2> /dev/null + if [ $? != 0 ]; then + echo "WARN: No JSON (input) files found in ${tdir} - skipping this dir" + continue + fi + tdir_name=$(basename $tdir) + + # for each config directory under $RULE + for rdir in ${ruledir}; do + + ls -l ${rdir}/*.groovy > /dev/null 2> /dev/null + if [ $? != 0 ]; then + echo "WARN: No Groovy (config) files found in ${rdir} - skipping this dir" + continue + fi + rdir_name=$(basename $rdir) + + echo "INFO: --------------------------------------------------------------------------------------" + echo "INFO: rule directory=$rdir_name" + echo "INFO: test directory=$tdir_name" + echo "INFO: --------------------------------------------------------------------------------------" + + # set actual and expected paths + actual=${ACTUAL}/${rdir_name}/${tdir_name} + expected=${EXPECTED}/${rdir_name}/${tdir_name} + + # create the actual result directory + # echo "INFO: mkdir -p ${actual}" + mkdir -p ${actual} + + # for each JSON file in $tdir + for json_file in ${tdir}/*.json ; do + + # execute each test twice + # once for http and once https + for protocol in http https; do + + # loop through each test + testcount=$((testcount + 1)) + + json_filename=$(basename $json_file) + + # remove the extn - use rev so that f1 is the last field not the first field + json_input=$(echo $json_filename | rev | cut -d'.' --complement -s -f1 | rev) + + # set port according to protocol + if [ "${protocol}" == "http" ]; then + port=9500 + else + port=9501 + fi + + echo -e "${TEST}: ${YELLOW_ON}$json_input${COLOUR_OFF} - POST request using ${protocol} protocol on port ${port}" + + if [ $verbose == "true" ]; then + echo -e "INFO: ${BLUE_ON}JSON payload to be validated${COLOUR_OFF}" + cat ${tdir}/${json_filename} + fi + + # POST JSON payload to the validation service + post_json_payload ${protocol} ${json_file} + + # Skip the test if the expected results file does not exist + if [ ! -e ${expected}/${json_input}.exp.json -a ! -e ${expected}/${json_input}.error ]; then + echo -e "${SKIP}: no ${json_input}.exp.json or ${json_input}.error file found" + skips=$((skips + 1)) + continue + fi + + if [ -e ${expected}/${json_input}.error ]; then + # not expecting a validation json payload, instead a plain text error message is returned + if [ -s ${actual}/${json_input}.res.json ]; then + # expecting a non-zero length file + # compare the actual results against the expected results + diff --strip-trailing-cr ${expected}/${json_input}.error ${actual}/${json_input}.res.json > ${actual}/${json_input}.diff + if [ $? != 0 ]; then + echo -e "${FAIL}: ${RED_ON}${json_input}${COLOUR_OFF} - POST response error text does not match expected result" + fails=$((fails + 1)) + else + echo -e "${PASS}: ${GREEN_ON}${json_input}${COLOUR_OFF} - POST response error text matches expected result" + passes=$((passes + 1)) + fi + else + # test fails if no POST response is returned + echo -e "${FAIL}: ${RED_ON}${json_input}${COLOUR_OFF} - No POST response returned" + fails=$((fails + 1)) + fi + continue + else + # expecting a non-zero length validation json payload to be returned + # Fail the test if the actual results file does not exist or is zero length + if [ ! -e ${actual}/${json_input}.res.json ]; then + echo -e "${FAIL}: ${RED_ON}${json_input}.res.json${COLOUR_OFF} - actual result file is missing" + fails=$((fails + 1)) + continue + else + if [ ! -s ${actual}/${json_input}.res.json ]; then + echo -e "${FAIL}: ${RED_ON}${json_input}.res.json${COLOUR_OFF} - actual result file is zero length (no JSON retrieved)" + fails=$((fails + 1)) + continue + fi + fi + + # compare the actual results against the expected results + diff --strip-trailing-cr ${expected}/${json_input}.exp.json ${actual}/${json_input}.res.json > ${actual}/${json_input}.diff + + diff_retval=$? + if [ "$diff_retval" == "0" ]; then + # actual and expected results match + # use python to format the json payload (raw output) + python -m json.tool ${actual}/${json_input}.raw.json > ${RUNNER}/pretty.json + if [ $verbose == "true" ]; then + # output the formatted validation payload + echo -e "INFO: ${BLUE_ON}validation result JSON payload${COLOUR_OFF}" + cat ${RUNNER}/pretty.json + echo -e "INFO: ${BLUE_ON}validation payload matches the expected result${COLOUR_OFF}" + fi + # report a test PASS status + echo -e "${PASS}: ${GREEN_ON}${json_input}${COLOUR_OFF} - POST response JSON payload matches expected result" + rm ${actual}/${json_input}.diff + passes=$((passes + 1)) + else + # actual and expected results do not match + fails=$((fails + 1)) + echo -e "${FAIL}: ${RED_ON}${json_input}${COLOUR_OFF} - POST response JSON payload does not match the expected result" + while read diffline + do + echo "DIFF: $diffline" + done < ${actual}/${json_input}.diff + fi + fi + done + done + done +done + +# output the test summary statistics +echo "INFO: ====================" +echo "INFO: Test Results Summary" +echo "INFO: ====================" + +testtotal=$((passes + fails + skips)) +if [ $testtotal != $testcount ]; then + echo "ERROR: test statistics are inconsistent!" +fi + +echo "Total passes = $passes" +echo "Total failures = $fails" +echo "Total skipped tests = $skips" +echo "Total tests executed = $testtotal" + + diff --git a/src/integration-test/resources/validation-service.properties b/src/integration-test/resources/validation-service.properties new file mode 100644 index 0000000..9321c41 --- /dev/null +++ b/src/integration-test/resources/validation-service.properties @@ -0,0 +1,27 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +topic.publish.enable=true +topic.publish.retries=3 +topic.consume.enable=true +topic.consume.polling.interval.seconds=7 + +event.domain=devINT1 +event.action.exclude=DELETE +event.type.rule=AAI-EVENT,AAI-DATA-EXPORT-API,GIZMO-EVENT,SPIKE-EVENT,EMPTY-RULESET-EVENT +event.type.model=AAI-DATA-EXPORT-NQ + +model.cache.expirySeconds=3 \ No newline at end of file diff --git a/src/main/bin/start.sh b/src/main/bin/start.sh new file mode 100644 index 0000000..9ce39f1 --- /dev/null +++ b/src/main/bin/start.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== + +# AJSC_HOME is required for EELF logging. +# This path is referenced in the file logback.xml. +AJSC_HOME="${AJSC_HOME-/opt/app/validation-service}" + +JARFILE="$AJSC_HOME/validation-service.jar" +LOGBACK_FILE=logback.xml + +# CONFIG_HOME is used as the base folder for relative paths, e.g. in the file aai-environment.properties +if [ -z "$CONFIG_HOME" ]; then + echo "CONFIG_HOME must be set in order to start up the process" + echo "E.g. CONFIG_HOME=${AJSC_HOME}/config" + exit 1 +fi + +# Some properties are repeated here for debugging purposes. +PROPS="-DAJSC_HOME=$AJSC_HOME" +PROPS="${PROPS} -DCONFIG_HOME=${CONFIG_HOME}" +PROPS="${PROPS} -Dcom.att.eelf.logging.path=${AJSC_HOME}" +PROPS="${PROPS} -Dcom.att.eelf.logging.file=${LOGBACK_FILE}" +PROPS="${PROPS} -Dlogback.configurationFile=${AJSC_HOME}/${LOGBACK_FILE}" +JVM_MAX_HEAP=${MAX_HEAP:-1024} + +if [ -z "${java_runtime_arguments}" ]; then + java_runtime_arguments="-Xms75m -Xmx${JVM_MAX_HEAP}m \ + -Dcom.sun.management.jmxremote \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=false \ + -Dcom.sun.management.jmxremote.local.only=false \ + -Dcom.sun.management.jmxremote.port=1099 \ + -Dcom.sun.management.jmxremote.rmi.port=1099 \ + -Djava.rmi.server.hostname=127.0.0.1" +fi + +echo "java $java_runtime_arguments $PROPS -jar $JARFILE" +java $java_runtime_arguments $PROPS -jar $JARFILE + diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile new file mode 100644 index 0000000..7f84abc --- /dev/null +++ b/src/main/docker/Dockerfile @@ -0,0 +1,53 @@ +# ============LICENSE_START=================================================== +# Copyright (c) 2018 Amdocs +# ============================================================================ +# 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===================================================== +FROM ubuntu:14.04 + +ARG MICRO_HOME=/opt/app/validation-service +ARG BIN_HOME=$MICRO_HOME/bin +ARG LOG_HOME=$MICRO_HOME/logs/AAI-VS +ARG JAR_FILE=validation-service.jar + +RUN apt-get update + +# Install and set up Java 8 +RUN apt-get update && apt-get install -y software-properties-common +## sudo -E is required to preserve the environment. If you remove that line, it will most like freeze at this step +RUN sudo -E add-apt-repository ppa:openjdk-r/ppa && apt-get update && apt-get install -y openjdk-8-jdk +## Set up JAVA_HOME for docker command-line +ENV JAVA_HOME usr/lib/jvm/java-8-openjdk-amd64 +RUN export JAVA_HOME + +# Build up the deployment folder structure +RUN mkdir -p $MICRO_HOME +COPY ${JAR_FILE} $MICRO_HOME/ +COPY classes/logback.xml $MICRO_HOME/ +COPY bundleconfig/ $MICRO_HOME/bundleconfig/ +RUN mkdir -p $BIN_HOME +COPY *.sh $BIN_HOME +RUN chmod 755 $BIN_HOME/* +RUN mkdir -p $LOG_HOME +RUN ln -s $MICRO_HOME/logs /logs + +# Create the aai user +RUN mkdir /opt/aaihome && \ + groupadd -g 492381 aaiadmin && \ + useradd -r -u 341790 -g 492381 -ms /bin/bash -d /opt/aaihome/aaiadmin aaiadmin && \ + chown -R aaiadmin:aaiadmin $MICRO_HOME +USER aaiadmin + +EXPOSE 9501 9501 + +CMD ["/opt/app/validation-service/bin/start.sh"] diff --git a/src/main/docker/readme.txt b/src/main/docker/readme.txt new file mode 100644 index 0000000..8ab5a22 --- /dev/null +++ b/src/main/docker/readme.txt @@ -0,0 +1,20 @@ +Brief steps on creating docker image manually. +============================================== + +1. build validation-service using + mvn clean install [-DskipTests] + +2. Build Docker image + sudo docker build -t openecomp/validation-service target + +3. Run docker image + sudo docker run -it -p 9501:9501 -v :/opt/app/validation-service/appconfig -v /etc/hosts:/etc/hosts openecomp/validation-service + eg. sudo docker run -it -p 9501:9501 -v /home/AAI/docker/validation/appconfig-local:/opt/app/validation-service/appconfig -v /etc/hosts:/etc/hosts openecomp/validation-service + +Troubleshooting +--------------- + +To run the docker image as an interactive bash shell + sudo docker run -it -p 9501:9501 -v /home/AAI/docker/validation/appconfig-local:/opt/app/validation-service/appconfig -v /etc/hosts:/etc/hosts openecomp/validation-service bash -il + + This will take you to a bash shell on the running docker container. cd to /opt/app/validation-service to check configurations or run it manually. diff --git a/src/main/java/org/onap/aai/auth/AAIAuthException.java b/src/main/java/org/onap/aai/auth/AAIAuthException.java new file mode 100644 index 0000000..5bbfc11 --- /dev/null +++ b/src/main/java/org/onap/aai/auth/AAIAuthException.java @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.auth; + +public class AAIAuthException extends Exception { + /** + * + */ + private static final long serialVersionUID = 1L; + + public AAIAuthException(String string) { + super(string); + } + + public AAIAuthException(String string, Exception e) { + super(string, e); + } + +} diff --git a/src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java new file mode 100644 index 0000000..fc40e0b --- /dev/null +++ b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java @@ -0,0 +1,103 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.auth; + +import java.security.cert.X509Certificate; +import javax.inject.Inject; +import javax.security.auth.x500.X500Principal; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Cookie; +import org.onap.aai.validation.config.ValidationServiceAuthConfig; +import org.onap.aai.validation.logging.LogHelper; + +public class AAIMicroServiceAuth { + + private static LogHelper applicationLogger = LogHelper.INSTANCE; + + private ValidationServiceAuthConfig validationServiceAuthConfig; + + @Inject + public AAIMicroServiceAuth(final ValidationServiceAuthConfig validationServiceAuthConfig) throws AAIAuthException { + this.validationServiceAuthConfig = validationServiceAuthConfig; + if (!validationServiceAuthConfig.isAuthenticationDisable()) { + AAIMicroServiceAuthCore.init(validationServiceAuthConfig.getAuthPolicyFile()); + } + } + + public boolean authBasic(String username, String authFunction) throws AAIAuthException { + return AAIMicroServiceAuthCore.authorize(username, authFunction); + } + + public String authUser(String authUser, String authFunction) throws AAIAuthException { + StringBuilder username = new StringBuilder(); + + username.append(authUser); + if (!authBasic(username.toString(), authFunction)) { + return "AAI_9101"; + + } + return "OK"; + } + + public boolean authCookie(Cookie cookie, String authFunction, StringBuilder username) throws AAIAuthException { + if (cookie == null) { + return false; + } + applicationLogger.debug("Got one:" + cookie); + + return AAIMicroServiceAuthCore.authorize(username.toString(), authFunction); + } + + public boolean validateRequest(HttpServletRequest req, String action, String apiPath) throws AAIAuthException { + + applicationLogger.debug("validateRequest: " + apiPath); + applicationLogger.debug("validationServiceConfig.isAuthenticationDisable(): " + + validationServiceAuthConfig.isAuthenticationDisable()); + + if (validationServiceAuthConfig.isAuthenticationDisable()) { + return true; + } + String[] ps = apiPath.split("/"); + String authPolicyFunctionName = ps[0]; + if (ps.length > 1) { + if (ps[0].matches("v\\d+")) { + authPolicyFunctionName = ps[1]; + } else { + authPolicyFunctionName = ps[0]; + } + } + + String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite"); + String authUser = null; + if (cipherSuite != null) { + X509Certificate[] certChain = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate"); + if (certChain != null) { + X509Certificate clientCert = certChain[0]; + X500Principal subjectDN = clientCert.getSubjectX500Principal(); + authUser = subjectDN.toString(); + } + } + + if (authUser == null) { + return false; + } + + String status = authUser(authUser.toLowerCase(), action + ":" + authPolicyFunctionName); + return "OK".equals(status); + } +} diff --git a/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java new file mode 100644 index 0000000..6a26a7a --- /dev/null +++ b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java @@ -0,0 +1,269 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.auth; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; +import org.onap.aai.validation.logging.ApplicationMsgs; +import org.onap.aai.validation.logging.LogHelper; + +/** + * Authentication and authorization by user and role. + */ +public class AAIMicroServiceAuthCore { + + private static LogHelper applicationLogger = LogHelper.INSTANCE; + + public static final String APPCONFIG_DIR = (System.getProperty("CONFIG_HOME") == null) + ? Paths.get(System.getProperty("AJSC_HOME"), "appconfig").toString() : System.getProperty("CONFIG_HOME"); + + private static Path appConfigAuthDir = Paths.get(APPCONFIG_DIR, "auth"); + private static Path defaultAuthFileName = appConfigAuthDir.resolve("auth_policy.json"); + + private static boolean usersInitialized = false; + private static HashMap users; + private static boolean timerSet = false; + private static String policyAuthFileName; + + public enum HTTP_METHODS { + GET, + PUT, + DELETE, + HEAD, + POST + } + + // Don't instantiate + private AAIMicroServiceAuthCore() {} + + public static String getDefaultAuthFileName() { + return defaultAuthFileName.toString(); + } + + public static void setDefaultAuthFileName(String defaultAuthFileName) { + AAIMicroServiceAuthCore.defaultAuthFileName = Paths.get(defaultAuthFileName); + } + + public static synchronized void init(String authPolicyFile) throws AAIAuthException { + + try { + policyAuthFileName = AAIMicroServiceAuthCore.getConfigFile(authPolicyFile); + } catch (IOException e) { + applicationLogger.debug("Exception while retrieving policy file."); + applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); + throw new AAIAuthException(e.getMessage()); + } + if (policyAuthFileName == null) { + throw new AAIAuthException("Auth policy file could not be found"); + } + AAIMicroServiceAuthCore.reloadUsers(); + + TimerTask task = new FileWatcher(new File(policyAuthFileName)) { + @Override + protected void onChange(File file) { + // here we implement the onChange + applicationLogger.debug("File " + file.getName() + " has been changed!"); + try { + AAIMicroServiceAuthCore.reloadUsers(); + } catch (AAIAuthException e) { + applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); + } + applicationLogger.debug("File " + file.getName() + " has been reloaded!"); + } + }; + + if (!timerSet) { + timerSet = true; + Timer timer = new Timer(); + long period = TimeUnit.SECONDS.toMillis(1); + timer.schedule(task, new Date(), period); + applicationLogger.debug("Config Watcher Interval = " + period); + } + } + + public static String getConfigFile(String authPolicyFile) throws IOException { + File authFile = new File(authPolicyFile); + if (authFile.exists()) { + return authFile.getCanonicalPath(); + } + authFile = appConfigAuthDir.resolve(authPolicyFile).toFile(); + if (authFile.exists()) { + return authFile.getCanonicalPath(); + } + if (getDefaultAuthFileName() != null) { + authFile = new File(getDefaultAuthFileName()); + if (authFile.exists()) { + return getDefaultAuthFileName(); + } + } + return null; + } + + /** + * @throws AAIAuthException + */ + public static synchronized void reloadUsers() throws AAIAuthException { + users = new HashMap<>(); + ObjectMapper mapper = new ObjectMapper(); + + try { + applicationLogger.debug("Reading from " + policyAuthFileName); + JsonNode rootNode = mapper.readTree(new File(policyAuthFileName)); + JsonNode rolesNode = rootNode.path("roles"); + + for (JsonNode roleNode : rolesNode) { + String roleName = roleNode.path("name").asText(); + AAIAuthRole r = new AAIAuthRole(); + JsonNode usersNode = roleNode.path("users"); + JsonNode functionsNode = roleNode.path("functions"); + for (JsonNode functionNode : functionsNode) { + addFunctionToRole(r, roleName, functionNode); + } + for (JsonNode userNode : usersNode) { + String name = userNode.path("username").asText().toLowerCase(); + AAIAuthUser user; + if (users.containsKey(name)) { + user = users.get(name); + } else { + user = new AAIAuthUser(); + } + + applicationLogger.debug("Assigning " + roleName + " to user " + name); + user.addRole(roleName, r); + users.put(name, user); + } + } + } catch (FileNotFoundException e) { + throw new AAIAuthException("Auth policy file could not be found", e); + } catch (JsonProcessingException e) { + throw new AAIAuthException("Error processing Auth policy file ", e); + } catch (IOException e) { + throw new AAIAuthException("Error reading Auth policy file", e); + } + + usersInitialized = true; + } + + /** + * @param role + * @param roleName + * @param functionNode + */ + private static void addFunctionToRole(AAIAuthRole role, String roleName, JsonNode functionNode) { + String functionName = functionNode.path("name").asText(); + JsonNode methodsNode = functionNode.path("methods"); + + if (methodsNode.size() == 0) { + for (HTTP_METHODS method : HTTP_METHODS.values()) { + String fullFunctionName = method.toString() + ":" + functionName; + applicationLogger.debug("Installing (all methods) " + fullFunctionName + " on role " + roleName); + role.addAllowedFunction(fullFunctionName); + } + } else { + for (JsonNode methodNode : methodsNode) { + String methodName = methodNode.path("name").asText(); + String fullFunctionName = methodName + ":" + functionName; + applicationLogger.debug("Installing function " + fullFunctionName + " on role " + roleName); + role.addAllowedFunction(fullFunctionName); + } + } + } + + public static class AAIAuthUser { + private HashMap roles; + + public AAIAuthUser() { + this.roles = new HashMap<>(); + } + + public void addRole(String roleName, AAIAuthRole r) { + this.roles.put(roleName, r); + } + + public boolean checkAllowed(String checkFunc) { + for (Entry role_entry : roles.entrySet()) { + AAIAuthRole role = role_entry.getValue(); + if (role.hasAllowedFunction(checkFunc)) { + return true; + } + } + return false; + } + + } + + public static class AAIAuthRole { + private List allowedFunctions; + + public AAIAuthRole() { + this.allowedFunctions = new ArrayList<>(); + } + + public void addAllowedFunction(String func) { + this.allowedFunctions.add(func); + } + + public void delAllowedFunction(String delFunc) { + if (this.allowedFunctions.contains(delFunc)) { + this.allowedFunctions.remove(delFunc); + } + } + + public boolean hasAllowedFunction(String functionName) { + return allowedFunctions.contains(functionName) ? true : false; + } + } + + public static boolean authorize(String username, String authFunction) throws AAIAuthException { + if (!usersInitialized || users == null) { + throw new AAIAuthException("Auth module not initialized"); + } + + if (users.containsKey(username)) { + if (users.get(username).checkAllowed(authFunction)) { + logAuthenticationResult(username, authFunction, "AUTH ACCEPTED"); + return true; + } else { + logAuthenticationResult(username, authFunction, "AUTH FAILED"); + return false; + } + } else { + logAuthenticationResult(username, authFunction, "User not found"); + return false; + } + } + + private static void logAuthenticationResult(String username, String authFunction, String result) { + applicationLogger.debug(result + ": " + username + " on function " + authFunction); + } + +} diff --git a/src/main/java/org/onap/aai/auth/FileWatcher.java b/src/main/java/org/onap/aai/auth/FileWatcher.java new file mode 100644 index 0000000..edc8bfe --- /dev/null +++ b/src/main/java/org/onap/aai/auth/FileWatcher.java @@ -0,0 +1,58 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.auth; + +import java.io.File; +import java.util.TimerTask; + +public abstract class FileWatcher extends TimerTask { + private long timeStamp; + private File file; + + /** + * Instantiates a new file watcher. + * + * @param file the file + */ + public FileWatcher(File file) { + this.file = file; + this.timeStamp = file.lastModified(); + } + + /** + * runs a timer task + * + * @see java.util.TimerTask.run + */ + @Override + public final void run() { + long newTimeStamp = file.lastModified(); + + if ((newTimeStamp - this.timeStamp) > 500) { + this.timeStamp = newTimeStamp; + onChange(file); + } + } + + /** + * On change. + * + * @param file the file + */ + protected abstract void onChange(File file); +} diff --git a/src/main/java/org/onap/aai/validation/ValidationServiceApplication.java b/src/main/java/org/onap/aai/validation/ValidationServiceApplication.java new file mode 100644 index 0000000..7e0e432 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/ValidationServiceApplication.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation; + +import java.util.HashMap; +import org.eclipse.jetty.util.security.Password; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.context.annotation.ImportResource; + +/** + * Validation Service Spring Boot Application. + */ + +@SpringBootApplication +@ImportResource("classpath:validation-service-beans.xml") +public class ValidationServiceApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + HashMap props = new HashMap<>(); + String keyStorePassword = System.getProperty("KEY_STORE_PASSWORD"); + if (keyStorePassword != null && !keyStorePassword.isEmpty()) { + props.put("server.ssl.key-store-password", Password.deobfuscate(keyStorePassword)); + } + new ValidationServiceApplication() + .configure(new SpringApplicationBuilder(ValidationServiceApplication.class).properties(props)) + .run(args); + } + +} diff --git a/src/main/java/org/onap/aai/validation/Validator.java b/src/main/java/org/onap/aai/validation/Validator.java new file mode 100644 index 0000000..c3ecc2a --- /dev/null +++ b/src/main/java/org/onap/aai/validation/Validator.java @@ -0,0 +1,45 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation; + +import java.util.List; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.result.ValidationResult; + +/** + * Validator (e.g. model-driven or rule-based) + * + */ +public interface Validator { + + /** + * This method should be called (once) before validate() to ensure that all configuration is correctly loaded. + * + * @throws ValidationServiceException + */ + public void initialise() throws ValidationServiceException; + + /** + * Validate the entity or entities found in the event. + * + * @param event JSON containing the entity or entities to validate + * @return a list of validation results + * @throws ValidationServiceException + */ + public List validate(String event) throws ValidationServiceException; +} diff --git a/src/main/java/org/onap/aai/validation/config/EventReaderConfig.java b/src/main/java/org/onap/aai/validation/config/EventReaderConfig.java new file mode 100644 index 0000000..c819351 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/config/EventReaderConfig.java @@ -0,0 +1,163 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.config; + +import org.springframework.beans.factory.annotation.Value; + +/** + * Loaded via Spring from src/main/resources/event-reader.properties. + */ +public class EventReaderConfig extends PropertiesConfig { + + @Value("${event.domain.path}") + private String eventDomainPath; + + @Value("${event.action.path}") + private String eventActionPath; + + @Value("${event.type.path}") + private String eventTypePath; + + @Value("${event.entity.type.path}") + private String entityTypePath; + + @Value("${event.entity.type.top.path}") + private String topEntityTypePath; + + @Value("${event.entity.link.path}") + private String entityLinkPath; + + @Value("${event.entity.link.delimiter}") + private String entityLinkDelimiter; + + @Value("${event.entity.path}") + private String entityPath; + + @Value("${event.entity.nested.path}") + private String nestedEntityPath; + + /** Entity relative path. Use when the entity has been extracted from the event. */ + @Value("${entity.id.path}") + private String entityIdPath; + + /** Entity relative path. Use when the entity has been extracted from the event. */ + @Value("${entity.resource.version.path}") + private String entityResourceVersionPath; + + public String getEventDomainPath() { + return eventDomainPath; + } + + public void setEventDomainPath(String eventDomainPath) { + this.eventDomainPath = eventDomainPath; + } + + public String getEventActionPath() { + return eventActionPath; + } + + public void setEventActionPath(String eventActionPath) { + this.eventActionPath = eventActionPath; + } + + public String getEventTypePath() { + return eventTypePath; + } + + public void setEventTypePath(String eventTypePath) { + this.eventTypePath = eventTypePath; + } + + public String getTopEntityTypePath() { + return topEntityTypePath; + } + + public void setTopEntityTypePath(String topEntityTypePath) { + this.topEntityTypePath = topEntityTypePath; + } + + public String getEntityLinkPath() { + return entityLinkPath; + } + + public void setEntityLinkPath(String entityLinkPath) { + this.entityLinkPath = entityLinkPath; + } + + public String getEntityLinkDelimiter() { + return entityLinkDelimiter; + } + + public void setEntityLinkDelimiter(String entityLinkDelimiter) { + this.entityLinkDelimiter = entityLinkDelimiter; + } + + public String getEntityTypePath() { + return entityTypePath; + } + + public void setEntityTypePath(String entityTypePath) { + this.entityTypePath = entityTypePath; + } + + public String getEntityPath() { + return entityPath; + } + + public void setEntityPath(String entityPath) { + this.entityPath = entityPath; + } + + /** + * Formats the nested entity path using the entity type provided. + * + * @param entityType + * an entity type + * @return the formatted nested entity path + */ + public String getNestedEntityPath(String entityType) { + return formatter(nestedEntityPath, entityType); + } + + public void setNestedEntityPath(String nestedEntityPath) { + this.nestedEntityPath = nestedEntityPath; + } + + /** + * Formats the entity ID path using the entity type provided. + * + * @param entityType + * an entity type + * @return the formatted entity ID path + */ + public String getEntityIdPath(String entityType) { + return formatter(entityIdPath, entityType); + } + + public void setEntityIdPath(String entityIdPath) { + this.entityIdPath = entityIdPath; + } + + public String getEntityResourceVersionPath() { + return entityResourceVersionPath; + } + + public void setEntityResourceVersionPath(String entityResourceVersionPath) { + this.entityResourceVersionPath = entityResourceVersionPath; + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/config/ModelConfig.java b/src/main/java/org/onap/aai/validation/config/ModelConfig.java new file mode 100644 index 0000000..02e14bc --- /dev/null +++ b/src/main/java/org/onap/aai/validation/config/ModelConfig.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.config; + +import org.springframework.beans.factory.annotation.Value; + +/** + * Model Configuration Bean + * + */ +public class ModelConfig { + + @Value("${model.cache.expirySeconds}") + private Long modelCacheExpirySeconds; + + public Long getModelCacheExpirySeconds() { + return modelCacheExpirySeconds; + } + + public void setModelCacheExpirySeconds(Long modelCacheExpirySeconds) { + this.modelCacheExpirySeconds = modelCacheExpirySeconds; + } + +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/config/PropertiesConfig.java b/src/main/java/org/onap/aai/validation/config/PropertiesConfig.java new file mode 100644 index 0000000..cf4bcb2 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/config/PropertiesConfig.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.config; + +import java.text.MessageFormat; + +/** + * Base properties configuration class. + */ +public class PropertiesConfig { + + /** + * Replaces place-holders in property values. + * + * @param s + * a string with place-holders in the form {n} + * @param args + * values for place-holders + * @return a formated String with replaced place-holders. + */ + public String formatter(String s, Object... args) { + MessageFormat formatter = new MessageFormat(""); + formatter.applyPattern(s); + return formatter.format(args); + } +} diff --git a/src/main/java/org/onap/aai/validation/config/RestConfig.java b/src/main/java/org/onap/aai/validation/config/RestConfig.java new file mode 100644 index 0000000..e99d6c2 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/config/RestConfig.java @@ -0,0 +1,225 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.config; + +import java.util.Objects; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.springframework.beans.factory.annotation.Value; + +/** + * Configuration required to establish REST client requests with an application. + */ +public class RestConfig { + + @Value("${host}") + private String host; + + @Value("${port}") + private Integer port; + + @Value("${httpProtocol}") + private String protocol; + + @Value("${baseModelURI}") + private String baseModelURI; + + @Value("${trustStorePath}") + private String trustStorePath; + + @Value("${trustStorePassword.x}") + private String trustStorePassword; + + @Value("${keyStorePath}") + private String keyStorePath; + + @Value("${keyStorePassword.x}") + private String keyStorePassword; + + @Value("${keyManagerFactoryAlgorithm}") + private String keyManagerFactoryAlgorithm; + + @Value("${keyStoreType}") + private String keyStoreType; + + @Value("${securityProtocol}") + private String securityProtocol; + + @Value("${connectionTimeout}") + private Integer connectionTimeout; + + @Value("${readTimeout}") + private Integer readTimeout; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getBaseModelURI() { + return baseModelURI; + } + + public void setBaseModelURI(String baseModelURI) { + this.baseModelURI = baseModelURI; + } + + public String getTrustStorePath() { + return trustStorePath; + } + + public void setTrustStorePath(String trustStorePath) { + this.trustStorePath = trustStorePath; + } + + /** + * Assumes the password is encrypted. + * + * @return the decrypted password + */ + public String getTrustStorePassword() { + return trustStorePassword; + } + + public void setTrustStorePassword(String trustStorePassword) { + this.trustStorePassword = trustStorePassword; + } + + public String getKeyStorePath() { + return keyStorePath; + } + + public void setKeyStorePath(String keyStorePath) { + this.keyStorePath = keyStorePath; + } + + /** + * Assumes the password is encrypted. + * + * @return the decrypted password + */ + public String getKeyStorePassword() { + return keyStorePassword; + } + + public void setKeyStorePassword(String keyStorePassword) { + this.keyStorePassword = keyStorePassword; + } + + public String getKeyManagerFactoryAlgorithm() { + return keyManagerFactoryAlgorithm; + } + + public void setKeyManagerFactoryAlgorithm(String keyManagerFactoryAlgorithm) { + this.keyManagerFactoryAlgorithm = keyManagerFactoryAlgorithm; + } + + public String getKeyStoreType() { + return keyStoreType; + } + + public void setKeyStoreType(String keyStoreType) { + this.keyStoreType = keyStoreType; + } + + public String getSecurityProtocol() { + return securityProtocol; + } + + public void setSecurityProtocol(String securityProtocol) { + this.securityProtocol = securityProtocol; + } + + public Integer getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(Integer connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public Integer getReadTimeout() { + return readTimeout; + } + + public void setReadTimeout(Integer readTimeout) { + this.readTimeout = readTimeout; + } + + @Override + public String toString() { + return "RestConfig [host=" + host + ", port=" + port + ", protocol=" + protocol + ", baseModelURI=" + + baseModelURI + ", trustStorePath=" + trustStorePath + ", trustStorePassword=" + trustStorePassword + + ", keyStorePath=" + keyStorePath + ", keyStorePassword=" + keyStorePassword + + ", keyManagerFactoryAlgorithm=" + keyManagerFactoryAlgorithm + ", keyStoreType=" + keyStoreType + + ", securityProtocol=" + securityProtocol + ", connectionTimeout=" + connectionTimeout + + ", readTimeout=" + readTimeout + "]"; + } + + @Override + public int hashCode() { + return Objects.hash(this.baseModelURI, this.connectionTimeout, this.host, this.keyManagerFactoryAlgorithm, + this.keyStorePassword, this.keyStorePath, this.keyStoreType, this.port, this.protocol, this.readTimeout, + this.securityProtocol, this.trustStorePassword, this.trustStorePath); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof RestConfig)) { + return false; + } else if (obj == this) { + return true; + } + RestConfig rhs = (RestConfig) obj; + // @formatter:off + return new EqualsBuilder() + .append(baseModelURI, rhs.baseModelURI) + .append(connectionTimeout, rhs.connectionTimeout) + .append(host, rhs.host) + .append(keyManagerFactoryAlgorithm, rhs.keyManagerFactoryAlgorithm) + .append(keyStorePassword, rhs.keyStorePassword) + .append(keyStorePath, rhs.keyStorePath) + .append(keyStoreType, rhs.keyStoreType) + .append(port, rhs.port) + .append(protocol, rhs.protocol) + .append(readTimeout, rhs.readTimeout) + .append(securityProtocol, rhs.securityProtocol) + .append(trustStorePassword, rhs.trustStorePassword) + .append(trustStorePath, rhs.trustStorePath) + .isEquals(); + // @formatter:on + } +} diff --git a/src/main/java/org/onap/aai/validation/config/RuleIndexingConfig.java b/src/main/java/org/onap/aai/validation/config/RuleIndexingConfig.java new file mode 100644 index 0000000..1d27705 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/config/RuleIndexingConfig.java @@ -0,0 +1,73 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.config; + +import java.util.List; + +/** + * Loads the properties needed by the controller using spring. + */ +public class RuleIndexingConfig extends PropertiesConfig { + + private List indexedEvents; + + private List excludedOxmValidationEvents; + + private List indexAttributes; + + private String defaultIndexKey; + + public List getIndexedEvents() { + return indexedEvents; + } + + public void setIndexedEvents(List indexedEvents) { + this.indexedEvents = indexedEvents; + } + + public List getExcludedOxmValidationEvents() { + return excludedOxmValidationEvents; + } + + public void setExcludedOxmValidationEvents(List excludedOxmValidationEvents) { + this.excludedOxmValidationEvents = excludedOxmValidationEvents; + } + + public List getIndexAttributes() { + return indexAttributes; + } + + public void setIndexAttributes(List indexAttributes) { + this.indexAttributes = indexAttributes; + } + + public String getDefaultIndexKey() { + return defaultIndexKey; + } + + public void setDefaultIndexKey(String defaultIndexKey) { + this.defaultIndexKey = defaultIndexKey; + } + + public boolean skipOxmValidation(String event) { + if(excludedOxmValidationEvents == null) { + return false; + } + return excludedOxmValidationEvents.contains(event); + } +} diff --git a/src/main/java/org/onap/aai/validation/config/TopicAdminConfig.java b/src/main/java/org/onap/aai/validation/config/TopicAdminConfig.java new file mode 100644 index 0000000..22fbe97 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/config/TopicAdminConfig.java @@ -0,0 +1,103 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.config; + +import java.util.Objects; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.springframework.beans.factory.annotation.Value; + +/** + * Configuration bean with topic administration properties that are loaded via Spring configuration. + */ +public class TopicAdminConfig { + + @Value("${topic.publish.enable}") + private boolean publishEnable; + + @Value("${topic.publish.retries}") + private Long publishRetries; + + @Value("${topic.consume.enable}") + private boolean consumeEnable; + + @Value("${topic.consume.polling.interval.seconds}") + private Long consumePollingIntervalSeconds; + + public boolean isPublishEnable() { + return publishEnable; + } + + public void setPublishEnable(boolean publishEnable) { + this.publishEnable = publishEnable; + } + + public Long getPublishRetries() { + return publishRetries; + } + + public void setPublishRetries(Long publishRetries) { + this.publishRetries = publishRetries; + } + + public boolean isConsumeEnable() { + return consumeEnable; + } + + public void setConsumeEnable(boolean consumeEnable) { + this.consumeEnable = consumeEnable; + } + + public Long getConsumePollingIntervalSeconds() { + return consumePollingIntervalSeconds; + } + + public void setConsumePollingIntervalSeconds(Long consumePollingIntervalSeconds) { + this.consumePollingIntervalSeconds = consumePollingIntervalSeconds; + } + + @Override + public int hashCode() { + return Objects.hash(this.consumeEnable, this.consumePollingIntervalSeconds, this.publishEnable, + this.publishRetries); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof TopicAdminConfig)) { + return false; + } else if (obj == this) { + return true; + } + TopicAdminConfig rhs = (TopicAdminConfig) obj; + // @formatter:off + return new EqualsBuilder() + .append(consumeEnable, rhs.consumeEnable) + .append(consumePollingIntervalSeconds, rhs.consumePollingIntervalSeconds) + .append(publishEnable, rhs.publishEnable) + .append(publishRetries, rhs.publishRetries) + .isEquals(); + // @formatter:on + } + + @Override + public String toString() { + return "TopicAdminConfig [publishEnable=" + publishEnable + ", publishRetries=" + publishRetries + + ", consumeEnable=" + consumeEnable + ", consumePollingIntervalSeconds=" + + consumePollingIntervalSeconds + "]"; + } +} diff --git a/src/main/java/org/onap/aai/validation/config/TopicConfig.java b/src/main/java/org/onap/aai/validation/config/TopicConfig.java new file mode 100644 index 0000000..ca04371 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/config/TopicConfig.java @@ -0,0 +1,228 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.config; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Properties; +import javax.annotation.Resource; +import org.apache.commons.lang3.builder.EqualsBuilder; + +/** + * Gets the configuration of the topics. The topics are configured using Spring in topic-config-beans.xml. + */ +public class TopicConfig { + + private List consumerTopicNames; + + private List publisherTopicNames; + + @Resource(name = "topicProperties") + private Properties topicProperties; + + List consumerTopics = new ArrayList<>(); + List publisherTopics = new ArrayList<>(); + + /** + * Gets the configuration of topics for consumption. + * + * @return a list of topic configurations. + */ + public List getConsumerTopics() { + return populateTopics(consumerTopics, consumerTopicNames); + } + + /** + * Gets the configuration of topics for publishing. + * + * @return a list of topic configurations. + */ + public List getPublisherTopics() { + return populateTopics(publisherTopics, publisherTopicNames); + } + + /** + * Populates the topics list with topic objects created from each item in the topicNames list. + * + * @param topics + * The topic list to populate. + * @param topicNames + * The list of topic names to populate the topic list with. + * @return The populated topic list. + */ + private List populateTopics(List topics, List topicNames) { + if (topics.isEmpty()) { + for (String topicName : topicNames) { + Topic topicConfig = new Topic(); + topicConfig.setName(getTopicProperties().getProperty(topicName + ".name")); + topicConfig.setHost(getTopicProperties().getProperty(topicName + ".host")); + topicConfig.setUsername(getTopicProperties().getProperty(topicName + ".username")); + topicConfig.setPassword(getTopicProperties().getProperty(topicName + ".password")); + topicConfig.setPartition(getTopicProperties().getProperty(topicName + ".publisher.partition")); + topicConfig.setConsumerGroup(getTopicProperties().getProperty(topicName + ".consumer.group")); + topicConfig.setConsumerId(getTopicProperties().getProperty(topicName + ".consumer.id")); + topicConfig.setTransportType(getTopicProperties().getProperty(topicName + ".transport.type")); + topics.add(topicConfig); + } + } + return topics; + } + + public List getConsumerTopicNames() { + return consumerTopicNames; + } + + public void setConsumerTopicNames(List consumerTopicNames) { + this.consumerTopicNames = consumerTopicNames; + } + + public List getPublisherTopicNames() { + return publisherTopicNames; + } + + public void setPublisherTopicNames(List publisherTopicNames) { + this.publisherTopicNames = publisherTopicNames; + } + + public Properties getTopicProperties() { + return topicProperties; + } + + public void setTopicProperties(Properties topicProperties) { + this.topicProperties = topicProperties; + } + + /** + * Defines the properties of a single topic for consumption. + */ + public class Topic { + private String name; + private String host; + private String username; + private String password; + private String partition; + private String consumerGroup; + private String consumerId; + private String transportType; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPartition() { + return partition; + } + + public void setPartition(String partition) { + this.partition = partition; + } + + public String getConsumerGroup() { + return consumerGroup; + } + + public void setConsumerGroup(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public String getConsumerId() { + return consumerId; + } + + public void setConsumerId(String consumerId) { + this.consumerId = consumerId; + } + + public List getHosts() { + return Arrays.asList(host.split(",")); + } + + public String getTransportType() { + return transportType; + } + + public void setTransportType(String transportType) { + this.transportType = transportType; + } + + @Override + public int hashCode() { + return Objects.hash(this.consumerGroup, this.consumerId, this.host, this.username, this.name, this.partition, + this.password, this.transportType); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Topic)) { + return false; + } else if (obj == this) { + return true; + } + Topic rhs = (Topic) obj; + // @formatter:off + return new EqualsBuilder() + .append(consumerGroup, rhs.consumerGroup) + .append(consumerId, rhs.consumerId) + .append(host, rhs.host) + .append(username, rhs.username) + .append(name, rhs.name) + .append(partition, rhs.partition) + .append(password, rhs.password) + .append(transportType, rhs.transportType) + .isEquals(); + // @formatter:on + } + + @Override + public String toString() { + return "Topic [name=" + name + ", host=" + host + ", username=" + username + ", password=" + password + ", partition=" + + partition + ", consumerGroup=" + consumerGroup + ", consumerId=" + consumerId + + ", transportType =" + transportType + "]"; + } + } +} diff --git a/src/main/java/org/onap/aai/validation/config/ValidationControllerConfig.java b/src/main/java/org/onap/aai/validation/config/ValidationControllerConfig.java new file mode 100644 index 0000000..4110175 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/config/ValidationControllerConfig.java @@ -0,0 +1,82 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.config; + +import java.util.List; +import org.springframework.beans.factory.annotation.Value; + +/** + * Loads the properties needed by the controller using spring. + */ +public class ValidationControllerConfig extends PropertiesConfig { + + @Value("${event.domain}") + private String eventDomain; + + @Value("#{'${event.action.exclude}'.split(',')}") + private List excludedEventActions; + + @Value("#{'${event.type.rule}'.split(',')}") + private List eventTypeRule; + + @Value("#{'${event.type.model}'.split(',')}") + private List eventTypeModel; + + @Value("${event.type.end:END-EVENT}") + private String eventTypeEnd; + + public String getEventDomain() { + return eventDomain; + } + + public void setEventDomain(String eventDomain) { + this.eventDomain = eventDomain; + } + + public List getExcludedEventActions() { + return excludedEventActions; + } + + public void setExcludedEventActions(List excludedEventActions) { + this.excludedEventActions = excludedEventActions; + } + + public List getEventTypeRule() { + return eventTypeRule; + } + + public void setEventTypeRule(List eventTypeRule) { + this.eventTypeRule = eventTypeRule; + } + + public List getEventTypeModel() { + return eventTypeModel; + } + + public void setEventTypeModel(List eventTypeModel) { + this.eventTypeModel = eventTypeModel; + } + + public String getEventTypeEnd() { + return eventTypeEnd; + } + + public void setEventTypeEnd(String eventTypeEnd) { + this.eventTypeEnd = eventTypeEnd; + } +} diff --git a/src/main/java/org/onap/aai/validation/config/ValidationServiceAuthConfig.java b/src/main/java/org/onap/aai/validation/config/ValidationServiceAuthConfig.java new file mode 100644 index 0000000..62280fa --- /dev/null +++ b/src/main/java/org/onap/aai/validation/config/ValidationServiceAuthConfig.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.config; + +import org.springframework.beans.factory.annotation.Value; + +public class ValidationServiceAuthConfig { + + @Value("${auth.authentication.disable}") + private boolean authenticationDisable; + + @Value("${auth.policy.file}") + private String authPolicyFile; + + public boolean isAuthenticationDisable() { + return authenticationDisable; + } + + public void setAuthenticationDisable(boolean authenticationDisable) { + this.authenticationDisable = authenticationDisable; + } + + public String getAuthPolicyFile() { + return authPolicyFile; + } + + public void setAuthPolicyFile(String authPolicyFile) { + this.authPolicyFile = authPolicyFile; + } + +} diff --git a/src/main/java/org/onap/aai/validation/controller/ValidationController.java b/src/main/java/org/onap/aai/validation/controller/ValidationController.java new file mode 100644 index 0000000..60d1c1c --- /dev/null +++ b/src/main/java/org/onap/aai/validation/controller/ValidationController.java @@ -0,0 +1,380 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.controller; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.SortedMap; +import java.util.TreeMap; +import javax.inject.Inject; +import org.onap.aai.validation.Validator; +import org.onap.aai.validation.config.ValidationControllerConfig; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.logging.ApplicationMsgs; +import org.onap.aai.validation.logging.LogHelper; +import org.onap.aai.validation.publisher.MessagePublisher; +import org.onap.aai.validation.reader.EventReader; +import org.onap.aai.validation.reader.data.Entity; +import org.onap.aai.validation.result.ValidationResult; +import org.onap.aai.validation.result.Violation; +import org.onap.aai.validation.util.JsonUtil; + +/** + * Controls the execution (of validation of an event) for the various validation service components. + */ +public class ValidationController { + + private static LogHelper applicationLogger = LogHelper.INSTANCE; + + public static final String VALIDATION_ERROR_SEVERITY = "CRITICAL"; + + private static final String VALIDATION_ERROR_CATEGORY = "CANNOT_VALIDATE"; + private static final String VALIDATION_ERROR_VIOLATIONTYPE = "NONE"; + + /** + * Result of the Controller executing validation of a single event. Either there is a set of ValidationResults or + * instead an exception was handled. + */ + public class Result { + /** + * A successful validation will produce a set of results. + */ + Optional> validationResults = Optional.empty(); + + /** + * For an unsuccessful validation, we will record the error details. + */ + private String errorText; + + /** + * @return whether or not we have a set of validation results + */ + public boolean validationSuccessful() { + return validationResults.isPresent(); + } + + public List getValidationResults() { + return validationResults.orElse(Collections.emptyList()); + } + + /** + * @return a JSON string representing the first ValidationResult, or an empty string when there are no results + */ + public String getValidationResultAsJson() { + List resultsList = getValidationResults(); + if (resultsList.isEmpty()) { + return ""; + } else { + // Only one Validation Result is returned (as only one is expected) + return JsonUtil.toJson(resultsList.get(0)); + } + } + + public Optional getErrorText() { + return Optional.ofNullable(errorText); + } + + private void handleException(String event, Exception rootException) { + try { + Entity entity = eventReader.getEntity(event); + if (!entity.getIds().isEmpty() && eventReader.getEntityType(event).isPresent() + && entity.getResourceVersion().isPresent()) { + ValidationResult validationResult = new ValidationResult(entity); + // @formatter:off + validationResult.addViolation(new Violation.Builder(entity) + .category(VALIDATION_ERROR_CATEGORY) + .severity(VALIDATION_ERROR_SEVERITY) + .violationType(VALIDATION_ERROR_VIOLATIONTYPE) + .errorMessage(rootException.getMessage()) + .build()); + // @formatter:on + + validationResults = Optional.of(Collections.singletonList(validationResult)); + publishValidationResults(validationResults); + } + } catch (Exception e) { + errorText = e.getMessage(); + applicationLogger.error(ApplicationMsgs.CANNOT_VALIDATE_HANDLE_EXCEPTION_ERROR, e, event); + } + } + } + + /** + * Status Report for the Controller + * + */ + public class StatusReport { + + private Temporal reportTime = LocalDateTime.now(); + private long upTime = ChronoUnit.SECONDS.between(startTime, reportTime); + private long upTimeDays = ChronoUnit.DAYS.between(startTime, reportTime); + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("Started at "); + sb.append(startTime).append('\n').append("Up time "); + if (upTimeDays > 0) { + sb.append(upTimeDays).append(" days "); + } + sb.append(LocalTime.MIDNIGHT.plusSeconds(upTime).format(DateTimeFormatter.ofPattern("HH:mm:ss"))); + sb.append('\n').append(formatStats(stats)); + return sb.toString(); + } + + /** + * @return formatted statistics + */ + private String formatStats(Statistics stats) { + StringBuilder sb = new StringBuilder(); + formatStats(stats, "info", sb, "Info Service"); + formatStats(stats, "http", sb, "Validation REST API"); + formatStats(stats, "topic", sb, "Events Consumed"); + if (stats.reportedThrowable != null) { + StringWriter sw = new StringWriter(); + stats.reportedThrowable.printStackTrace(new PrintWriter(sw)); + sb.append("Exception reported: ").append(sw.toString()); + } + return sb.toString(); + } + + private void formatStats(Statistics stats, String eventSource, StringBuilder sb, String heading) { + sb.append("\n").append(heading).append("\n"); + if (stats.keyValues(eventSource).isEmpty()) { + sb.append("total=0\n"); + } else { + for (String key : stats.keyValues(eventSource)) { + sb.append(key).append("=").append(stats.messageCount(eventSource, key)).append("\n"); + } + } + } + } + + private ValidationControllerConfig validationControllerConfig; + private EventReader eventReader; + private Validator ruleDrivenValidator; + private Validator modelDrivenValidator; + private MessagePublisher messagePublisher; + private LocalDateTime startTime; + private Statistics stats; + + /** + * Record of actions taken by the Controller + * + */ + private class Statistics { + + private Map> sourceMap = new HashMap<>(); + private Throwable reportedThrowable; + + /** + * Increment the message count for the composite key + * + * @param eventSource the source of the event - used for statistics reporting purposes + * @param key the statistic to increment by one + */ + private void incrementEventCount(String eventSource, String key) { + Map messagesConsumed = getMessageCountsMap(eventSource); + int count = messagesConsumed.getOrDefault(key, 0); + messagesConsumed.put(key, count + 1); + } + + private Map getMessageCountsMap(String eventSource) { + return sourceMap.computeIfAbsent(eventSource, k -> new TreeMap<>()); + } + + /** + * @param eventSource the source of the event + * @return List the keys for the specified eventSource + */ + private List keyValues(String eventSource) { + Map messagesConsumed = getMessageCountsMap(eventSource); + return new ArrayList<>(messagesConsumed.keySet()); + } + + /* + * return the count for the supplied event source and statistic key + */ + private int messageCount(String eventSource, String key) { + Map messagesConsumed = getMessageCountsMap(eventSource); + return messagesConsumed.getOrDefault(key, 0); + } + + } + + /** + * Constructs a new validation controller with the injected parameters. + * + * @param validationControllerConfig the configuration parameters for validation controllers + * @param eventReader an object that can read events + * @param ruleDrivenValidator a validator for validating rules + * @param modelDrivenValidator a validator for validating model + * @param messagePublisher an instance of a publisher for messages + */ + @Inject + public ValidationController(ValidationControllerConfig validationControllerConfig, EventReader eventReader, + Validator ruleDrivenValidator, Validator modelDrivenValidator, MessagePublisher messagePublisher) { + this.startTime = LocalDateTime.now(); + this.validationControllerConfig = validationControllerConfig; + this.eventReader = eventReader; + this.ruleDrivenValidator = ruleDrivenValidator; + this.modelDrivenValidator = modelDrivenValidator; + this.messagePublisher = messagePublisher; + this.stats = new Statistics(); + } + + /** + * @throws ValidationServiceException if an error occurs initialising the controller + */ + public void initialise() throws ValidationServiceException { + ruleDrivenValidator.initialise(); + modelDrivenValidator.initialise(); + } + + /** + * Validates the event and publishes the results of the validation onto the topic configured in the message + * publisher. + * + * @param event the event to be validated + * @param eventSource the source of the event + * @return Result a result containing either the set of ValidationResults or an error message + */ + public Result execute(String event, String eventSource) { + Result result = new Result(); + try { + stats.incrementEventCount(eventSource, "total"); + if (isEndEvent(event)) { + applicationLogger.debug("Event has not been processed. End event type was detected. Event :" + event); + stats.incrementEventCount(eventSource, "end"); + } else if (isValidationCandidate(event)) { + result.validationResults = dispatchEvent(event, eventSource); + publishValidationResults(result.validationResults); + } else { + stats.incrementEventCount(eventSource, "filtered"); + } + } catch (Exception e) { + applicationLogger.error(ApplicationMsgs.CANNOT_VALIDATE_ERROR, e, event); + stats.incrementEventCount(eventSource, "errored"); + result.handleException(event, e); + } + return result; + } + + private void publishValidationResults(Optional> validationResults) { + if (validationResults.isPresent()) { + for (ValidationResult validationResult : validationResults.get()) { + try { + messagePublisher.publishMessage(validationResult.toJson()); + } catch (ValidationServiceException e) { + applicationLogger.error(ApplicationMsgs.MESSAGE_PUBLISH_ERROR, e, validationResult.toString()); + } + } + } + } + + private Optional> dispatchEvent(String event, String eventSource) + throws ValidationServiceException { + List validationResults = null; + Optional eventType = eventReader.getEventType(event); + + applicationLogger.debug("Event consumed: " + event); + + if (eventType.isPresent()) { + if (isRuleDriven(eventType.get())) { + validationResults = ruleDrivenValidator.validate(event); + stats.incrementEventCount(eventSource, "rule"); + } else if (isModelDriven(eventType.get())) { + validationResults = modelDrivenValidator.validate(event); + stats.incrementEventCount(eventSource, "model"); + } else { + applicationLogger.debug("Event has not been validated. Invalid event type. Event :" + event); + stats.incrementEventCount(eventSource, "invalid"); + } + } else { + stats.incrementEventCount(eventSource, "missing event type"); + } + + return Optional.ofNullable(validationResults); + } + + private Boolean isRuleDriven(String eventType) { + return validationControllerConfig.getEventTypeRule().contains(eventType); + } + + private Boolean isModelDriven(String eventType) { + return validationControllerConfig.getEventTypeModel().contains(eventType); + } + + private boolean isEndEvent(String event) throws ValidationServiceException { + Optional eventType = eventReader.getEventType(event); + + return eventType.isPresent() && "END-EVENT".equalsIgnoreCase(eventType.get()); + } + + private Boolean isDomainValid(String event) throws ValidationServiceException { + Optional eventDomain = eventReader.getEventDomain(event); + + // Domain is optional in Event Header + return !eventDomain.isPresent() + || validationControllerConfig.getEventDomain().equalsIgnoreCase(eventDomain.get()); + } + + private Boolean isNotExcludedAction(String event) throws ValidationServiceException { + Optional eventAction = eventReader.getEventAction(event); + + // Action is optional in Event Header + return !eventAction.isPresent() + || !validationControllerConfig.getExcludedEventActions().contains(eventAction.get()); + } + + + private Boolean isValidationCandidate(String event) throws ValidationServiceException { + return isDomainValid(event) && isNotExcludedAction(event); + } + + /** + * @return a formatted string containing status information + */ + public StatusReport statusReport() { + return new StatusReport(); + } + + /** + * Record a Throwable which will then be added to the status reporting text. + * + * @param t a Throwable to be reported (on demand) + */ + public void recordThrowable(Throwable t) { + stats.reportedThrowable = t; + } + + public void incrementInfoCount() { + stats.incrementEventCount("info", "total"); + } + +} diff --git a/src/main/java/org/onap/aai/validation/data/client/RestClient.java b/src/main/java/org/onap/aai/validation/data/client/RestClient.java new file mode 100644 index 0000000..d2d1196 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/data/client/RestClient.java @@ -0,0 +1,121 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.data.client; + +import com.sun.jersey.core.util.MultivaluedMapImpl; +import java.util.Arrays; +import java.util.UUID; +import javax.inject.Inject; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.validation.config.RestConfig; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; + +/** + * REST client capable of establishing secured requests. + */ +public class RestClient { + private RestConfig restConfig; + private org.onap.aai.restclient.client.RestClient aaiRestClient; + private MultivaluedMap headers; + + private static final String ACCEPT = "application/json"; + private static final String HEADER_X_FROM_APP_ID = "validation-service"; + private static final String APP_CONFIG_HOME = System.getProperty("CONFIG_HOME"); + + /** + * Constructs a new rest client with the injected parameters. + * + * @param restConfig + */ + @Inject + public RestClient(RestConfig restConfig) { + this.restConfig = restConfig; + initialiseRestClient(); + } + + /** + * Initialises the REST client + * + */ + private void initialiseRestClient() { + // @formatter:off + aaiRestClient = new org.onap.aai.restclient.client.RestClient() + .validateServerHostname(false) + .validateServerCertChain(true) + .clientCertFile(APP_CONFIG_HOME + restConfig.getKeyStorePath()) + .clientCertPassword(restConfig.getKeyStorePassword()) + .trustStore(APP_CONFIG_HOME + restConfig.getTrustStorePath()) + .connectTimeoutMs(restConfig.getConnectionTimeout()) + .readTimeoutMs(restConfig.getReadTimeout()); + // @formatter:on + + headers = new MultivaluedMapImpl(); + headers.put("Accept", Arrays.asList(ACCEPT)); + headers.put("X-FromAppId", Arrays.asList(HEADER_X_FROM_APP_ID)); + headers.put("X-TransactionId", Arrays.asList(UUID.randomUUID().toString())); + } + + /** + * Invokes the REST URL and returns the payload string. + * + * @param uriPath + * @param mediaType + * @return The payload of the REST URL call as a string. + * @throws ValidationServiceException + */ + public String get(String uriPath, String mediaType) throws ValidationServiceException { + // Construct URI + String uri = restConfig.getProtocol() + "://" + restConfig.getHost() + ":" + restConfig.getPort() + uriPath; + + OperationResult result = aaiRestClient.get(uri, headers, MediaType.valueOf(mediaType)); + + if (result.getResultCode() == 200) { + return result.getResult(); + } else if (result.getResultCode() == 404) { + throw new ValidationServiceException(ValidationServiceError.REST_CLIENT_RESPONSE_NOT_FOUND, + result.getResultCode(), result.getFailureCause()); + } else { + throw new ValidationServiceException(ValidationServiceError.REST_CLIENT_RESPONSE_ERROR, + result.getResultCode(), result.getFailureCause()); + } + } + + /** + * POSTs a request. + * + * @param url + * @param payload + * + * @return The payload of the REST URL call as a string. + * @throws GapServiceException + */ + public String post(String url, String payload) throws ValidationServiceException { + OperationResult result = aaiRestClient.post(url, payload, headers, MediaType.APPLICATION_JSON_TYPE, + MediaType.APPLICATION_JSON_TYPE); + if (result.getResultCode() == 200) { + return result.getResult(); + } else { + throw new ValidationServiceException(ValidationServiceError.REST_CLIENT_RESPONSE_ERROR, + result.getResultCode(), result.getFailureCause()); + } + + } +} diff --git a/src/main/java/org/onap/aai/validation/exception/BaseValidationServiceException.java b/src/main/java/org/onap/aai/validation/exception/BaseValidationServiceException.java new file mode 100644 index 0000000..59fdb72 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/exception/BaseValidationServiceException.java @@ -0,0 +1,66 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.exception; + +import java.util.Locale; + +/** + * Validation service exception base class + * + */ +public class BaseValidationServiceException extends Exception { + + private static final long serialVersionUID = -6663403070792969748L; + + public static final Locale LOCALE = Locale.US; + + private final String id; + + /** + * Default constructor. + * + * @param id + */ + public BaseValidationServiceException(String id) { + super(); + this.id = id; + } + + /** + * @param id + * @param message + */ + public BaseValidationServiceException(String id, String message) { + super(message); + this.id = id; + } + + /** + * @param id + * @param message + * @param cause + */ + public BaseValidationServiceException(String id, String message, Throwable cause) { + super(message, cause); + this.id = id; + } + + public String getId() { + return this.id; + } +} diff --git a/src/main/java/org/onap/aai/validation/exception/ValidationServiceError.java b/src/main/java/org/onap/aai/validation/exception/ValidationServiceError.java new file mode 100644 index 0000000..45d79d4 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/exception/ValidationServiceError.java @@ -0,0 +1,103 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.exception; + +import java.text.MessageFormat; + +/** + * Error text formatting + * + */ +public enum ValidationServiceError { + + //@formatter:off + + // Rule Configuration exceptions. Range 100..199 + RULES_FILE_ERROR("VS-100", "Error reading rules configuration file(s) {0}"), + RULE_UNEXPECTED_TOKEN("VS-101", "Token {0} unexpected in rules configuration file."), + RULES_NOT_DEFINED("VS-102", "Event type {0} has no rule definitions."), + + // Rule exceptions. Range 200..299 + RULE_EXECUTION_ERROR("VS-201", "Error executing rule {0} with arguments {1}"), + + // Validation service processing exceptions. Range 300..399 + OMX_LOAD_ERROR("VS-300", "Validation service failed to load the OXM file."), + OXM_MISSING_KEY("VS-301", "Validation service failed to retrieve primary key for object of type {0}."), + MESSAGE_DIGEST_ERROR("VS-302", "Java platform security error. Failed to create Message Digest hashing object {0}."), + MODEL_RETRIEVAL_ERROR("VS-303", "Validator failed to get the model from external system."), + MODEL_CACHE_ERROR("VS-304", "Validator failed to retrieve the model from the cache. {0}"), + MODEL_NOT_FOUND("VS-305", "Model with UUID {0} not found."), + + // Event publishing exceptions. Range 400..499 + EVENT_CLIENT_PUBLISHER_INIT_ERROR("VS-400", "Error while initialising the Event Publisher Client."), + EVENT_CLIENT_SEND_ERROR("VS-401", "Error while sending a message to the event bus."), + EVENT_CLIENT_INCORRECT_NUMBER_OF_MESSAGES_SENT("VS-402", "Publisher client returned a result of {0} messages sent."), + EVENT_CLIENT_CLOSE_ERROR("VS-403", "Error while closing the Event Publisher Client."), + EVENT_CLIENT_CLOSE_UNSENT_MESSAGE("VS-404", "Failed to publish message. Error while closing the Event Publisher Client. " + + "The following message is unsent: {0}. Please check the logs for more information."), + EVENT_CLIENT_CONSUMER_INIT_ERROR("VS-405", "Error while initialising the Event Consumer Client."), + + // Reader exceptions. Range 500..599 + JSON_READER_PARSE_ERROR("VS-500", "JSON could not be parsed."), + EVENT_READER_MISSING_PROPERTY("VS-501", "Missing property: {0}"), + EVENT_READER_TOO_MANY_ENTITIES("VS-502", "Unexpected number or entities."), + INSTANCE_READER_NO_INSTANCE("VS-503", "Failed to extract instance under path: {0}. JSON payload: {1}"), + EVENT_READER_PROPERTY_READ_ERROR("VS-504", "Failed to read entity link property. Check event reader configuration properties."), + + // Model-instance mapping exceptions. Range 600..649 + MODEL_INSTANCE_MAPPING_RETRIEVAL_ERROR("VS-600", "Error retrieving model-instance mappings."), + MODEL_INSTANCE_MAPPING_FILE_IO_ERROR("VS-601", "IO error when reading from the model-instance mapping file {0}."), + MODEL_PARSE_ERROR("VS-602", "Validator failed to parse the model provided. Source:\n{0}"), + MODEL_VALUE_ERROR("VS-603", "Validator failed to access the model value {0} in {1}"), + INSTANCE_MAPPING_ROOT_ERROR("VS-604", "Missing 'root' property in instance mapping."), + + // REST client exceptions. Range 650..699 + REST_CLIENT_RESPONSE_ERROR("VS-650", "REST client response error: Response Code: {0}, Failure Cause: {1}."), + REST_CLIENT_RESPONSE_NOT_FOUND("VS-651", "REST client response error: Response Code: {0}, Failure Cause: {1}."), + + // Validation Service configuration exceptions. Range 700..799 + VS_PROPERTIES_LOAD_ERROR("VS-700", "Failed to read property {0} in the validation service properties file."), + + // Miscellaneous exceptions. Range 800..849 + STRING_UTILS_INVALID_REGEX("VS-800", "Invalid regular expression: {0}"); + + //@formatter:on + + private String id; + private String message; + + private ValidationServiceError(String id, String message) { + this.id = id; + this.message = message; + } + + public String getId() { + return this.id; + } + + /** + * @param args + * to be formatted + * @return the formatted error message + */ + public String getMessage(Object... args) { + MessageFormat formatter = new MessageFormat(""); + formatter.applyPattern(this.message); + return formatter.format(args); + } +} diff --git a/src/main/java/org/onap/aai/validation/exception/ValidationServiceException.java b/src/main/java/org/onap/aai/validation/exception/ValidationServiceException.java new file mode 100644 index 0000000..2606ce9 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/exception/ValidationServiceException.java @@ -0,0 +1,78 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.exception; + +/** + * Validation service exception + * + */ +public class ValidationServiceException extends BaseValidationServiceException { // NOSONAR + + private static final long serialVersionUID = 883498159309797607L; + + /** + * Constructs an exception defined by the Error. + * + * @param error + * {@link ValidationServiceError} with the error id. + */ + public ValidationServiceException(ValidationServiceError error) { + super(error.getId(), error.getId() + ", " + error.getMessage()); + } + + /** + * Constructs an exception defined by the Error. The message is parameterised with the arguments. + * + * @param error + * {@link ValidationServiceError} with the error id. + * @param args + * Arguments for the exception message. + */ + public ValidationServiceException(ValidationServiceError error, Object... args) { + super(error.getId(), error.getId() + ", " + error.getMessage(args)); + } + + /** + * Constructs an exception defined by the Error and the underlying Exception. The message is parameterised with the + * arguments and enhanced with the underlying Exception message. + * + * @param error + * {@link ValidationServiceError} with the error id. + * @param exception + * Exception thrown by an underlying API. + * @param args + * Arguments for the exception message. + */ + public ValidationServiceException(ValidationServiceError error, Exception exception, Object... args) { + super(error.getId(), error.getId() + ", " + error.getMessage(args) + "; Caused by: " + exception.getMessage(), exception); + } + + /** + * Constructs an exception defined by the Error and the underlying Exception. The message is enhanced with the + * underlying Exception message. + * + * @param error + * {@link ValidationServiceError} with the error id. + * @param exception + * Exception thrown by an underlying API. + */ + public ValidationServiceException(ValidationServiceError error, Exception exception) { + super(error.getId(), error.getId() + ", " + error.getMessage() + "; Caused by: " + exception.getMessage(), exception); + } + +} diff --git a/src/main/java/org/onap/aai/validation/factory/DMaaPEventPublisherFactory.java b/src/main/java/org/onap/aai/validation/factory/DMaaPEventPublisherFactory.java new file mode 100644 index 0000000..fa4af74 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/factory/DMaaPEventPublisherFactory.java @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.factory; + +import org.onap.aai.event.client.DMaaPEventPublisher; + +public class DMaaPEventPublisherFactory { + + + public DMaaPEventPublisher createEventPublisher(String topicHost, String topicName, String topicUsername, + String topicPassword, String topicTransportType) { + int defaultBatchSize = DMaaPEventPublisher.DEFAULT_BATCH_SIZE; + long defaultBatchAge = DMaaPEventPublisher.DEFAULT_BATCH_AGE; + int defaultBatchDelay = DMaaPEventPublisher.DEFAULT_BATCH_DELAY; + return new DMaaPEventPublisher(topicHost, topicName, topicUsername, topicPassword, defaultBatchSize, + defaultBatchAge, defaultBatchDelay, topicTransportType); + } + +} diff --git a/src/main/java/org/onap/aai/validation/logging/ApplicationMsgs.java b/src/main/java/org/onap/aai/validation/logging/ApplicationMsgs.java new file mode 100644 index 0000000..6066a20 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/logging/ApplicationMsgs.java @@ -0,0 +1,74 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.logging; + +import com.att.eelf.i18n.EELFResourceManager; +import org.onap.aai.cl.eelf.LogMessageEnum; + +/** + * Application messages + */ +public enum ApplicationMsgs implements LogMessageEnum { + + /** + * Add message keys here. + */ + // @formatter:off + MESSAGE_VALIDATION_REQUEST, + MESSAGE_AUDIT, + MESSAGE_METRIC, + MESSAGE_PUBLISH_ERROR, + OXM_LOAD_ERROR, + OXM_MISSING_KEY_ERROR, + MISSING_REQUEST_ID, + CANNOT_VALIDATE_ERROR, + CANNOT_VALIDATE_HANDLE_EXCEPTION_ERROR, + POLL_EVENTS, + NUMBER_OF_MESSAGES_CONSUMED, + INVOKE_EVENT_CONSUMER_ERROR, + READ_FILE_ERROR, + STARTUP_SERVLET_INIT, + POLLING_INTERVAL_CONFIG_NOT_PRESENT, + POLLING_FOR_EVENTS, + POLLING_DISABLED, + STARTUP_SERVLET_INIT_SUCCESS, + UNSENT_MESSAGE_WARN, + UNSENT_MESSAGE_ERROR, + EVENT_CLIENT_CLOSE_UNSENT_MESSAGE, + SEND_MESSAGE_ABORT_WARN, + SEND_MESSAGE_RETRY_WARN, + FILE_ARG_NULL_ERROR, + LOAD_PROPERTIES, + FILE_LOAD_INTO_MAP, + FILE_LOAD_INTO_MAP_ERROR, + CREATE_PROPERTY_MAP_ERROR, + FILE_MONITOR_BLOCK_ERROR, + READ_FILE_STREAM_ERROR, + STRING_UTILS_INVALID_REGEX, + MALFORMED_REQUEST_ERROR, + PROCESS_REQUEST_ERROR; + // @formatter:on + + /** + * Static initializer to ensure the resource bundles for this class are loaded... Here this application loads + * messages from three bundles + */ + static { + EELFResourceManager.loadMessageBundle("validation-service-logging-resources"); + } +} diff --git a/src/main/java/org/onap/aai/validation/logging/LogHelper.java b/src/main/java/org/onap/aai/validation/logging/LogHelper.java new file mode 100644 index 0000000..4abf5fd --- /dev/null +++ b/src/main/java/org/onap/aai/validation/logging/LogHelper.java @@ -0,0 +1,548 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.logging; + +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + +import ch.qos.logback.classic.AsyncAppender; +import ch.qos.logback.core.FileAppender; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResolvableErrorEnum; +import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import javax.servlet.ServletRequest; +import javax.ws.rs.core.Response.Status; +import org.apache.commons.lang.time.StopWatch; +import org.onap.aai.cl.api.LogFields; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.cl.mdc.MdcOverride; +import org.onap.aai.restclient.client.Headers; +import org.onap.aai.validation.services.RequestHeaders; +import org.slf4j.MDC; +import org.springframework.http.HttpHeaders; + +/*- + * This Log Helper mimics the interface of a Common Logging Logger + * but adds helper methods for audit and metrics logging requirements. + * + * Messages are logged to the appropriate EELF functional logger as described below. + * + * Error Log: INFO/WARN/ERROR/FATAL + * Debug Log: DEBUG/TRACE + * Audit Log: summary view of transaction processing + * Metrics Log: detailed timings of transaction processing interactions + * + * Audit and Metrics log messages record the following fields: + * + * RequestID - an RFC4122 UUID for the transaction request + * ServiceName - the API provided by this service + * PartnerName - invoker of the API + * ClassName - name of the class creating the log record + * + * The above list is not exhaustive. + */ +public enum LogHelper implements Logger { + INSTANCE; // Joshua Bloch's singleton pattern + + @FunctionalInterface + public interface TriConsumer { + public void accept(T t, U u, V v); + } + + /** + * Audit log message status code values. See {@code MdcParameter.STATUS_CODE} + */ + public enum StatusCode { + COMPLETE, + ERROR; + } + + /** + * Mapped Diagnostic Context parameter names. + * + * Note that MdcContext.MDC_START_TIME is used for audit messages, and indicates the start of a transaction. + * Messages in the metrics log record sub-operations of a transaction and thus use different timestamps. + */ + public enum MdcParameter { + REQUEST_ID(MdcContext.MDC_REQUEST_ID), + CLASS_NAME("ClassName"), + BEGIN_TIMESTAMP("BeginTimestamp"), + END_TIMESTAMP("EndTimestamp"), + ELAPSED_TIME("ElapsedTime"), + STATUS_CODE("StatusCode"), + RESPONSE_CODE("ResponseCode"), + RESPONSE_DESCRIPTION("ResponseDescription"), + TARGET_ENTITY("TargetEntity"), + TARGET_SERVICE_NAME("TargetServiceName"), + USER("User"); + + private final String parameterName; + + MdcParameter(String parameterName) { + this.parameterName = parameterName; + } + + /** + * Get the MDC logging context parameter name as referenced by the logback configuration + * + * @return the MDC parameter name + */ + public String value() { + return parameterName; + } + } + + /** + * Our externally advertised service API + */ + private static final String SERVICE_NAME_VALUE = "AAI-VS"; + + private static final EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger(); + private static final EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger(); + private static final EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger(); + private static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + + /** + * Formatting for timestamps logged as Strings (from the MDC) + */ + private DateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); + + // Records the elapsed time (since the start of servicing a request) for audit logging + private StopWatch auditStopwatch; + + /** + * Initialises the MDC (logging context) with default values, to support any logging of messages BEFORE the + * startAudit() method is invoked. + */ + private LogHelper() { + setContextValue(MDC_SERVICE_NAME, SERVICE_NAME_VALUE); + // This value is not expected to be used in the default logging configuration + setContextValue(MdcContext.MDC_START_TIME, timestampFormat.format(new Date())); + } + + /** + * Begin recording transaction information for a new request. This data is intended for logging purposes. This + * method does not actually write any messages to the log(s). + * + * Initialise the MDC logging context for auditing and metrics, using the HTTP request headers. This information + * includes: the correlation ID, local application service name/ID, calling host details and authentication data. + * + * The request object is used to find the client details (e.g. IP address) + * + * @param headers raw HTTP headers + * @param servletRequest the request + */ + public void startAudit(final HttpHeaders headers, ServletRequest servletRequest) { + auditStopwatch = new StopWatch(); + auditStopwatch.start(); + + String requestId = null; + String serviceInstanceId = null; + String partnerName = ""; + + if (headers != null) { + requestId = setRequestId(headers); + serviceInstanceId = headers.getFirst(RequestHeaders.HEADER_SERVICE_INSTANCE_ID); + partnerName = headers.getFirst(Headers.FROM_APP_ID); + } + + String clientHost = null; + String clientIPAddress = null; + String user = ""; + + if (servletRequest != null) { + clientHost = servletRequest.getRemoteHost(); + clientIPAddress = servletRequest.getRemoteAddr(); + + if (partnerName == null) { + partnerName = clientHost; + } + } + + // Populate standard MDC keys - note that the initialize method calls MDC.clear() + MdcContext.initialize(requestId, SERVICE_NAME_VALUE, serviceInstanceId, partnerName, clientIPAddress); + + setContextValue(MdcParameter.USER, user); + setContextValue(MdcContext.MDC_REMOTE_HOST, clientHost); + } + + /** + * Store a value in the current thread's logging context. + * + * @param key non-null parameter name + * @param value the value to store against the key + */ + public void setContextValue(String key, String value) { + debug(key + "=" + value); + MDC.put(key, value); + } + + /** + * Store a value in the current thread's logging context. + * + * @param param identifier of the context parameter + * @param value the value to store for this parameter + */ + public void setContextValue(MdcParameter param, String value) { + setContextValue(param.value(), value); + } + + /** + * Set a value in the current thread's logging context, only if this is not already set. + * + * @param key non-null parameter name + * @param value the value to store against the key (only if the current value is null) + */ + public void setDefaultContextValue(String key, String value) { + if (MDC.get(key) == null) { + setContextValue(key, value); + } + } + + /** + * Set a value in the current thread's logging context, only if this is not already set. + * + * @param param identifier of the context parameter + * @param value the value to store for this parameter (only if the current value is null) + */ + public void setDefaultContextValue(MdcParameter param, String value) { + setContextValue(param.value(), value); + } + + /** + * Clear all logging context values. This should be called at start-up only. + */ + public void clearContext() { + debug("Clearing MDC context"); + MDC.clear(); + } + + /** + * Clear the specified logging context value. + */ + public void clearContextValue(MdcParameter param) { + MDC.remove(param.value()); + } + + /** + * Log an audit message to the audit logger. This method is expected to be called when a response is returned to the + * caller and/or when the processing of the request completes. + * + * @param status status of the service request: COMPLETE/ERROR + * @param responseCode optional application error code + * @param responseDescription human-readable description of the response code + * @param args the argument(s) required to populate the Audit Message log content + */ + public void logAudit(StatusCode status, String responseCode, String responseDescription, final String... args) { + if (auditStopwatch == null) { + debug("Unexpected program state: audit stopwatch not started"); + auditStopwatch = new StopWatch(); + auditStopwatch.start(); + } + + if (auditLogger.isInfoEnabled()) { + setMdcElapsedTime(auditStopwatch); + setContextValue(MdcParameter.STATUS_CODE, status.toString()); + setContextValue(MdcParameter.RESPONSE_CODE, responseCode); + setContextValue(MdcParameter.RESPONSE_DESCRIPTION, responseDescription); + invokeLogger(auditLogger::info, ApplicationMsgs.MESSAGE_AUDIT, args); + } + } + + /** + * Log an audit message to the audit logger representing a non-specific processing success message. + * + * @param msg + */ + public void logAuditSuccess(String msg) { + Status status = Status.OK; + logAudit(StatusCode.COMPLETE, Integer.toString(status.getStatusCode()), status.getReasonPhrase(), msg); + } + + /** + * Log an audit message to the audit logger representing an internal error (e.g. for an exception thrown by the + * implementation). This method is expected to be called when a generic error response is returned to the caller to + * indicate a processing failure. + * + * @param e Exception + */ + public void logAuditError(Exception e) { + Status status = Status.INTERNAL_SERVER_ERROR; + logAudit(StatusCode.ERROR, Integer.toString(status.getStatusCode()), status.getReasonPhrase(), e.getMessage()); + } + + /** + * Log a message to the metrics log. + * + * @param error the log code + * @param args the info messages + */ + public void logMetrics(final String... args) { + if (metricsLogger.isInfoEnabled()) { + invokeLogger(metricsLogger::info, ApplicationMsgs.MESSAGE_METRIC, args); + } + } + + /** + * @param stopwatch + * @param args + */ + public void logMetrics(final StopWatch stopwatch, String... args) { + setMdcElapsedTime(stopwatch); + logMetrics(args); + } + + @Override + public String formatMsg(@SuppressWarnings("rawtypes") Enum arg0, String... args) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isDebugEnabled() { + return debugLogger != null && debugLogger.isDebugEnabled(); + } + + @Override + public boolean isErrorEnabled() { + return errorLogger.isErrorEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return errorLogger.isInfoEnabled(); + } + + @Override + public boolean isTraceEnabled() { + return debugLogger.isTraceEnabled(); + } + + @Override + public boolean isWarnEnabled() { + return errorLogger.isWarnEnabled(); + } + + /** + * Log a DEBUG level message to the debug logger. + * + * @param message the debug message + */ + @Override + public void debug(String message) { + if (isDebugEnabled()) { + invokeLogger(debugLogger::debug, message); + } + } + + @Override + public void debug(@SuppressWarnings("rawtypes") Enum errorCode, String... args) { + if (isDebugEnabled()) { + invokeErrorCodeLogger(debugLogger::debug, (EELFResolvableErrorEnum) errorCode, args); + } + } + + @Override + public void debug(@SuppressWarnings("rawtypes") Enum errorCode, LogFields arg1, String... args) { + throw new UnsupportedOperationException(); + } + + @Override + public void error(@SuppressWarnings("rawtypes") Enum errorCode, String... args) { + if (isErrorEnabled()) { + invokeErrorCodeLogger(errorLogger::error, (EELFResolvableErrorEnum) errorCode, args); + } + } + + @Override + public void error(@SuppressWarnings("rawtypes") Enum errorCode, Throwable t, String... args) { + if (isErrorEnabled()) { + invokeErrorCodeLogger(errorLogger::error, (EELFResolvableErrorEnum) errorCode, t, args); + } + } + + @Override + public void error(@SuppressWarnings("rawtypes") Enum errorCode, LogFields arg1, String... args) { + throw new UnsupportedOperationException(); + } + + @Override + public void error(@SuppressWarnings("rawtypes") Enum errorCode, LogFields arg1, Throwable arg2, String... args) { + throw new UnsupportedOperationException(); + } + + @Override + public void info(@SuppressWarnings("rawtypes") Enum errorCode, String... args) { + if (isInfoEnabled()) { + invokeErrorCodeLogger(errorLogger::info, (EELFResolvableErrorEnum) errorCode, args); + } + } + + @Override + public void info(@SuppressWarnings("rawtypes") Enum arg0, LogFields arg1, String... args) { + throw new UnsupportedOperationException(); + } + + @Override + public void info(@SuppressWarnings("rawtypes") Enum arg0, LogFields arg1, MdcOverride arg2, String... args) { + throw new UnsupportedOperationException(); + } + + @Override + public void trace(@SuppressWarnings("rawtypes") Enum errorCode, String... args) { + if (isTraceEnabled()) { + invokeErrorCodeLogger(debugLogger::trace, (EELFResolvableErrorEnum) errorCode, args); + } + } + + @Override + public void trace(@SuppressWarnings("rawtypes") Enum arg0, LogFields arg1, String... args) { + throw new UnsupportedOperationException(); + } + + @Override + public void warn(@SuppressWarnings("rawtypes") Enum errorCode, String... args) { + if (isWarnEnabled()) { + invokeErrorCodeLogger(errorLogger::warn, (EELFResolvableErrorEnum) errorCode, args); + } + } + + @Override + public void warn(@SuppressWarnings("rawtypes") Enum arg0, LogFields arg1, String... args) { + throw new UnsupportedOperationException(); + } + + /** + * Get the method name for a calling method (from the current stack trace) + * + * @param level number of levels for the caller (not including this method) + * @return the class and name of the calling method in the form "class#method" + */ + public static String getCallerMethodName(int level) { + StackTraceElement callingMethod = Thread.currentThread().getStackTrace()[level + 2]; + return callingMethod.getClassName() + "#" + callingMethod.getMethodName(); + } + + + /** + * Convenience method to be used only for testing purposes. + * + * @return the directory storing the log files + */ + public static String getLogDirectory() { + ch.qos.logback.classic.Logger logger = + (ch.qos.logback.classic.Logger) org.slf4j.LoggerFactory.getLogger("com.att.eelf"); + AsyncAppender appender = (AsyncAppender) logger.getAppender("asyncEELF"); + FileAppender fileAppender = (FileAppender) appender.getAppender("EELF"); + return new File(fileAppender.getFile()).getParent(); + } + + /** + * @param headers + * @return the request ID from the HTTP headers + */ + private String setRequestId(final HttpHeaders headers) { + String requestId = headers.getFirst(RequestHeaders.HEADER_REQUEST_ID); + + // If the request ID is missing, set it from the transaction ID + if (requestId == null) { + requestId = headers.getFirst(Headers.TRANSACTION_ID); + } + + // Normalize the incoming ID by removing any suffix + if (requestId != null && requestId.contains(":")) { + requestId = requestId.split(":")[0]; + } + + return requestId == null ? "missing-request-id" : requestId; + } + + private void setMdcClassName() { + MDC.put(MdcParameter.CLASS_NAME.value(), getCallerMethodName(3)); + } + + private void unsetMdcClassName() { + MDC.put(MdcParameter.CLASS_NAME.value(), null); + } + + /** + * Set the Begin, End, and Elapsed time values in the MDC context. + * + * @param stopwatch + */ + private void setMdcElapsedTime(final StopWatch stopwatch) { + long startTime = stopwatch.getStartTime(); + long elapsedTime = stopwatch.getTime(); + + setContextValue(MdcParameter.BEGIN_TIMESTAMP, timestampFormat.format(startTime)); + setContextValue(MdcParameter.END_TIMESTAMP, timestampFormat.format(startTime + elapsedTime)); + setContextValue(MdcParameter.ELAPSED_TIME, Long.toString(elapsedTime)); // Milliseconds + } + + /** + * @param logMethod the logger method to invoke + * @param message + */ + private void invokeLogger(Consumer logMethod, String message) { + setMdcClassName(); + logMethod.accept(message); + unsetMdcClassName(); + } + + /** + * @param logMethod + * @param msg + * @param args + */ + private void invokeLogger(BiConsumer logMethod, ApplicationMsgs msg, String[] args) { + setMdcClassName(); + logMethod.accept(msg, args); + unsetMdcClassName(); + } + + /** + * @param logMethod + * @param errorEnum + * @param args + */ + private void invokeErrorCodeLogger(BiConsumer logMethod, + EELFResolvableErrorEnum errorEnum, String[] args) { + setMdcClassName(); + logMethod.accept(errorEnum, args); + unsetMdcClassName(); + } + + /** + * @param logMethod + * @param errorEnum + * @param t a Throwable + * @param args + */ + private void invokeErrorCodeLogger(TriConsumer logMethod, + EELFResolvableErrorEnum errorEnum, Throwable t, String[] args) { + setMdcClassName(); + logMethod.accept(errorEnum, t, args); + unsetMdcClassName(); + } + +} diff --git a/src/main/java/org/onap/aai/validation/modeldriven/ModelCacheManager.java b/src/main/java/org/onap/aai/validation/modeldriven/ModelCacheManager.java new file mode 100644 index 0000000..5c741fb --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/ModelCacheManager.java @@ -0,0 +1,182 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import javax.inject.Inject; +import javax.ws.rs.core.MediaType; +import org.apache.http.client.utils.URIBuilder; +import org.dom4j.Element; +import org.onap.aai.validation.config.ModelConfig; +import org.onap.aai.validation.config.RestConfig; +import org.onap.aai.validation.data.client.RestClient; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.modeldriven.parser.XMLModelParser; + +/** + * A cache of model UUID against the parsed model Element, using Guava's CacheBuilder. + */ +public class ModelCacheManager { + + public static final String FILE_MODEL_PROTOCOL = "file"; + + private LoadingCache modelCache; + private RestConfig restConfig; + + /** + * Initialises the instance by loading validator properties from config. + * + * @param modelConfig + * @param restConfig + * @throws ValidationServiceException + */ + @Inject + public ModelCacheManager(ModelConfig modelConfig, RestConfig restConfig) { + this.restConfig = restConfig; + + // Create an expiring cache with a load implementation which is executed when a key value is not cached. + modelCache = CacheBuilder.newBuilder().maximumSize(1000) + .expireAfterWrite(modelConfig.getModelCacheExpirySeconds(), TimeUnit.SECONDS) + .build(new CacheLoader() { + @Override + public Element load(ModelId key) throws ValidationServiceException { + return retrieveModelElement(key); + } + }); + } + + /** + * Gets the model with specified uuid from the model cache. If model is not cached, retrieve the model from the + * external system. + * + * @param uuid + * The model UUID. + * @return The DOM Element representing the model's root element. + * @throws ValidationServiceException + */ + public Element get(ModelId uuid) throws ValidationServiceException { + if (uuid == null || uuid.isEmpty()) { + return null; + } + + return getCachedModel(uuid); + } + + private Element getCachedModel(ModelId uuid) throws ValidationServiceException { + Element element = null; + try { + element = modelCache.get(uuid); + } catch (ExecutionException e) { + // If the wrapped exception is a model validation error, return null. + Throwable cause = e.getCause(); + if (cause != null && cause.getClass().equals(ValidationServiceException.class) + && (((ValidationServiceException) cause).getId().equals(ValidationServiceError.MODEL_NOT_FOUND.getId()) + || ((ValidationServiceException) cause).getId().equals(ValidationServiceError.REST_CLIENT_RESPONSE_NOT_FOUND.getId()))) { + return null; + } + throw new ValidationServiceException(ValidationServiceError.MODEL_CACHE_ERROR, e, ""); + } + return element; + } + + /** + * Puts an item into the model cache. + * + * @param uuid + * The key. + * @param modelElement + * The value. + */ + public void put(ModelId uuid, Element modelElement) { + modelCache.put(uuid, modelElement); + } + + /** + * Constructs and invokes the configured REST URL. The XML payload is then parsed into a model Element. + * + * @param uuid + * The model UUID to retrieve. + * @return The payload of the REST URL call as a model Element. + * @throws ValidationServiceException + * if the payload is null + */ + private Element retrieveModelElement(ModelId uuid) throws ValidationServiceException { + String protocol = restConfig.getProtocol(); + Element modelElement; + if (FILE_MODEL_PROTOCOL.equals(protocol)) { + File modelFile = new File(restConfig.getBaseModelURI()); + modelElement = retrieveModelElementFromFile(modelFile, uuid); + } else { + modelElement = retrieveModelElementFromREST(restConfig, uuid); + } + + // Do not store a null value in the CacheBuilder + if (modelElement != null) { + return modelElement; + } else { + throw new ValidationServiceException(ValidationServiceError.MODEL_NOT_FOUND, uuid); + } + } + + /** + * Constructs and invokes the configured REST URL to retrieve the model for the supplied UUID. The XML payload is + * then parsed into a model Element. + * + * @param uuid + * The model UUID to retrieve. + * @return The payload of the REST URL call as a model Element, or null of no model could be found. + * @throws ValidationServiceException + */ + private Element retrieveModelElementFromREST(RestConfig restConfig, ModelId uuid) + throws ValidationServiceException { + try { + URI restURI = new URIBuilder(restConfig.getBaseModelURI()) + .addParameter(uuid.getModelIdAttribute(), uuid.getModelId()).build(); + String restPayload = new RestClient(restConfig).get(restURI.toString(), MediaType.APPLICATION_XML); + return XMLModelParser.parse(restPayload, true); + } catch (URISyntaxException e) { + throw new ValidationServiceException(ValidationServiceError.MODEL_RETRIEVAL_ERROR, e); + } + } + + /** + * Retrieves the model with supplied model UUID from the supplied model file. The XML payload is then parsed into a + * model Element. + * + * @param uuid + * The model UUID to retrieve. + * @return The model Element, or null if no model could be found. + * @throws ValidationServiceException + */ + private Element retrieveModelElementFromFile(File modelFile, ModelId uuid) throws ValidationServiceException { + Element rootElement = XMLModelParser.parse(modelFile, false); + // Check that the root element of the model file is correct. + if (!XMLModelParser.MODELS_ROOT_ELEMENT.equals(rootElement.getName())) { + return null; + } + return XMLModelParser.getModelElementWithId(rootElement, uuid.getModelIdAttribute(), uuid.getModelId()); + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/modeldriven/ModelId.java b/src/main/java/org/onap/aai/validation/modeldriven/ModelId.java new file mode 100644 index 0000000..25fbc22 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/ModelId.java @@ -0,0 +1,86 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven; + +import java.util.Objects; +import org.apache.commons.lang3.builder.EqualsBuilder; + +/** + * Bean representing a model ID. + * + * The modelIdAttribute field defines the attribute in the model that holds the modelId + */ +public class ModelId { + + public static final String ATTR_MODEL_NAME_VERSION_ID = "model-name-version-id"; + public static final String ATTR_MODEL_ID = "model-id"; + + private String modelIdAttribute; + private String id; + + /** + * @param modelIdAttribute The name of the attribute that holds the model ID. + * @param modelId The model ID. + */ + public ModelId(String modelIdAttribute, String modelId) { + super(); + this.modelIdAttribute = modelIdAttribute; + this.id = modelId; + } + + public String getModelIdAttribute() { + return modelIdAttribute; + } + + public void setModelIdAttribute(String modelIdAttribute) { + this.modelIdAttribute = modelIdAttribute; + } + + public String getModelId() { + return id; + } + + public void setModelId(String modelId) { + this.id = modelId; + } + + public boolean isEmpty() { + return modelIdAttribute == null || id == null || modelIdAttribute.isEmpty() || id.isEmpty(); + } + + @Override + public int hashCode() { + return Objects.hash(this.id, this.modelIdAttribute); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ModelId)) { + return false; + } else if (obj == this) { + return true; + } + ModelId rhs = (ModelId) obj; + // @formatter:off + return new EqualsBuilder() + .append(id, rhs.id) + .append(modelIdAttribute, rhs.modelIdAttribute) + .isEquals(); + // @formatter:on + } +} diff --git a/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/Filter.java b/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/Filter.java new file mode 100644 index 0000000..a251d54 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/Filter.java @@ -0,0 +1,75 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven.configuration.mapping; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import org.apache.commons.lang3.builder.EqualsBuilder; + +/** + * Defines a path and value that will be used to validate a particular model. + * @see ValueConfiguration and ModelInstanceMapper + */ +public class Filter { + + private String path; + private List valid = new ArrayList<>(); + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public List getValid() { + return valid; + } + + public void setValid(List valid) { + this.valid = valid; + } + + @Override + public int hashCode() { + return Objects.hash(path, valid); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Filter)) { + return false; + } else if (obj == this) { + return true; + } + Filter rhs = (Filter) obj; + // @formatter:off + return new EqualsBuilder() + .append(path, rhs.path) + .append(valid, rhs.valid) + .isEquals(); + // @formatter:on + } + + @Override + public String toString() { + return "Filter [path=" + path + ", valid=" + valid + "]"; + } +} diff --git a/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/ModelInstanceMapper.java b/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/ModelInstanceMapper.java new file mode 100644 index 0000000..9ebe03c --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/ModelInstanceMapper.java @@ -0,0 +1,89 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven.configuration.mapping; + +import java.util.Objects; +import org.apache.commons.lang3.builder.EqualsBuilder; + +/** + * Maps the configuration of model and instance values to be compared. + */ +public class ModelInstanceMapper { + + /** + * Types of mappings. + */ + public enum MappingType { + RELATIONSHIP, ATTRIBUTE + } + + private MappingType mappingType; + private ValueConfiguration model; + private ValueConfiguration instance; + + public MappingType getMappingType() { + return mappingType; + } + + public void setMappingType(String mappingType) { + this.mappingType = MappingType.valueOf(mappingType); + } + + public ValueConfiguration getModel() { + return model; + } + + public void setModel(ValueConfiguration model) { + this.model = model; + } + + public ValueConfiguration getInstance() { + return instance; + } + + public void setInstance(ValueConfiguration instance) { + this.instance = instance; + } + + @Override + public int hashCode() { + return Objects.hash(instance, mappingType, model); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ModelInstanceMapper)) { + return false; + } else if (obj == this) { + return true; + } + ModelInstanceMapper rhs = (ModelInstanceMapper) obj; + // @formatter:off + return new EqualsBuilder() + .append(instance, rhs.instance) + .append(mappingType, rhs.mappingType) + .append(model, rhs.model) + .isEquals(); + // @formatter:on + } + + @Override + public String toString() { + return "ModelInstanceMapper [mappingType=" + mappingType + ", model=" + model + ", instance=" + instance + "]"; + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/ModelInstanceMappingReader.java b/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/ModelInstanceMappingReader.java new file mode 100644 index 0000000..7be2d76 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/ModelInstanceMappingReader.java @@ -0,0 +1,69 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven.configuration.mapping; + +import java.util.ArrayList; +import java.util.List; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.util.JsonUtil; + +/** + * Read mapping files + */ +public class ModelInstanceMappingReader { + + private String mappingFile; + + /** + * @param mappingFile + */ + public ModelInstanceMappingReader(String mappingFile) { + this.mappingFile = mappingFile; + } + + /** + * Returns a list of model and object instance paths that will be used for comparing the corresponding model and + * instance elements. The mappings are defined in the configuration file model-instance-mapping.json_conf and follows the + * JSON notation. + * + * @return a List of {@link ModelInstanceMapper} beans which represents all the mappings defined in the file + * model-instance-mapping.json_conf. + * @throws ValidationServiceException + */ + public List getMappings() throws ValidationServiceException { + List mappings = new ArrayList<>(); + + try { + JSONArray mappingsArray = new JSONArray(mappingFile); + + for (int i = 0; i < mappingsArray.length(); i++) { + JSONObject jsonObject = mappingsArray.getJSONObject(i); + ModelInstanceMapper mapping = JsonUtil.fromJson(jsonObject.toString(), ModelInstanceMapper.class); + mappings.add(mapping); + } + } catch (JSONException e) { + throw new ValidationServiceException(ValidationServiceError.MODEL_INSTANCE_MAPPING_RETRIEVAL_ERROR, e); + } + + return mappings; + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/ValueConfiguration.java b/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/ValueConfiguration.java new file mode 100644 index 0000000..230bbd9 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/configuration/mapping/ValueConfiguration.java @@ -0,0 +1,124 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven.configuration.mapping; + +import java.util.Objects; +import org.apache.commons.lang3.builder.EqualsBuilder; + +/** + * Describes a model or instance value that is used in model to instance comparison. + * + * @see ModelInstanceMapper + */ +public class ValueConfiguration { + + /** Top level element. From which all navigation starts. */ + private String origin; + + /** + * Root element from which the value will be extracted. Can be used to recursively navigate the model/instance + * hierarchy. + */ + private String root; + + /** + * Provides validation on the model before the value is extracted. If the filter is not satisfied other root models + * will be searched. + */ + private Filter filter; + + /** + * Path to the model id + */ + private String id; + + /** + * Path to a model or instance value + */ + private String value; + + public String getOrigin() { + return origin; + } + + public void setOrigin(String origin) { + this.origin = origin; + } + + public String getRoot() { + return root; + } + + public void setRoot(String root) { + this.root = root; + } + + public Filter getFilter() { + return filter; + } + + public void setFilter(Filter filter) { + this.filter = filter; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public int hashCode() { + return Objects.hash(this.filter, this.origin, this.root, this.value, this.id); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ValueConfiguration)) { + return false; + } else if (obj == this) { + return true; + } + ValueConfiguration rhs = (ValueConfiguration) obj; + // @formatter:off + return new EqualsBuilder() + .append(filter, rhs.filter) + .append(origin, rhs.origin) + .append(root, rhs.root) + .append(value, rhs.value) + .append(id, rhs.id) + .isEquals(); + // @formatter:on + } + + @Override + public String toString() { + return "ValueConfiguration [origin=" + origin + ", root=" + root + ", id=" + id + ", filter=" + filter + + ", value=" + value + "]"; + } +} diff --git a/src/main/java/org/onap/aai/validation/modeldriven/parser/XMLModelParser.java b/src/main/java/org/onap/aai/validation/modeldriven/parser/XMLModelParser.java new file mode 100644 index 0000000..cf7aa38 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/parser/XMLModelParser.java @@ -0,0 +1,152 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven.parser; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.List; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.dom4j.Node; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; + +/** + * Read models from XML file + * + */ +public class XMLModelParser { + + public static final String MODEL_ROOT_ELEMENT = "model"; + public static final String MODELS_ROOT_ELEMENT = "models"; + + private XMLModelParser() { + // Do nothing + } + + /** + * Parses an xml file and returns the root Element. + * + * @param modelFile + * The XML File. + * @param validateModel + * If true the model will be validated. + * @return The root Element of the document. + * @throws DocumentException + * @throws ValidationServiceException + */ + public static Element parse(File modelFile, boolean validateModel) throws ValidationServiceException { + try { + byte[] encoded = Files.readAllBytes(modelFile.toPath()); + String modelString = new String(encoded, Charset.defaultCharset()); + + return parse(modelString, validateModel); + } catch (IOException e) { + throw new ValidationServiceException(ValidationServiceError.MODEL_PARSE_ERROR, e, modelFile.toString()); + } + } + + /** + * Parses an xml String and returns the root Element. + * + * @param modelString + * The XML String. + * @param validateModel + * If true the model will be validated. + * @return The root Element of the document, or null if no valid model can be parsed. + * @throws DocumentException + */ + public static Element parse(String modelString, boolean validateModel) throws ValidationServiceException { + // Strip namespace information first. + String model = removeXmlStringNamespaceAndPreamble(modelString); + + try { + Element modelElement = DocumentHelper.parseText(model).getRootElement(); + if (validateModel && (modelElement == null || !isValidModel(modelElement))) { + return null; + } + return modelElement; + } catch (DocumentException e) { + throw new ValidationServiceException(ValidationServiceError.MODEL_PARSE_ERROR, e, model); + } + } + + /** + * Returns the result of running the XPath expression on the DOM Node. + * + * @param currentNode + * The current Node being processed. + * @param xPath + * The XPath expression to run on the Node. + * @return A List of Nodes representing the result of the XPath expression. + */ + @SuppressWarnings("unchecked") + public static List getObjectsFromXPath(Node currentNode, String xPath) { + return currentNode.selectNodes(xPath); + } + + /** + * Returns the child model Element that corresponds to the provided root Element and model ID. + * + * @param rootElement + * The root Element to search. + * @param attributeName + * The name of the attribute that holds the model ID. + * @param modelId + * The model ID to search for. + * @return The model Element that matches the model ID supplied. + */ + public static Element getModelElementWithId(Element rootElement, String attributeName, String modelId) { + Element modelElement = null; + List modelsList = getObjectsFromXPath(rootElement, MODEL_ROOT_ELEMENT + "/" + attributeName); + for (Node model : modelsList) { + if (model.getText().equals(modelId)) { + modelElement = model.getParent(); + } + } + return modelElement; + } + + /** + * Determines the validity of the supplied model element by checking if the name of the root element is correct. + * + * @param modelElement + * The model element to check. + * @return True if the root element matches the expected name. + */ + private static boolean isValidModel(Element modelElement) { + return MODEL_ROOT_ELEMENT.equals(modelElement.getName()); + } + + /** + * Strips all namespace information from the model XML. + * + * @param modelXML + * The model XML as a String. + * @return The model XML String minus the namespace information. + */ + private static String removeXmlStringNamespaceAndPreamble(String xmlString) { + return xmlString.replaceAll("(<\\?[^<]*\\?>)?", "") /* remove preamble */ + .replaceAll("xmlns.*?(\"|\').*?(\"|\')", "") /* remove xmlns declaration */ + .replaceAll("(<)(\\w+:)(.*?>)", "$1$3") /* remove opening tag prefix */ + .replaceAll("()", "$1$3"); /* remove closing tags prefix */ + } +} diff --git a/src/main/java/org/onap/aai/validation/modeldriven/validator/InstanceReader.java b/src/main/java/org/onap/aai/validation/modeldriven/validator/InstanceReader.java new file mode 100644 index 0000000..7832e51 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/validator/InstanceReader.java @@ -0,0 +1,316 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven.validator; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.jayway.jsonpath.DocumentContext; +import java.util.Arrays; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; +import javax.inject.Inject; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMapper; +import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMapper.MappingType; +import org.onap.aai.validation.reader.JsonReader; +import org.onap.aai.validation.reader.OxmReader; + +/** + * Reads values from an instance object. + */ +public class InstanceReader { + + private static final String MODEL_NAME = "model-name"; + private static final String[] INVALID_ENTRIES = { "inventory-response-items", "extra-properties", MODEL_NAME }; + private static final String RESOURCE_VERSION = "resource-version"; + private static final String JSON_PATH_MODEL_ID = "$.*.persona-model-id"; + + private JsonReader jsonReader; + private OxmReader oxmReader; + private JsonParser jsonParser = new JsonParser(); + + /** + * @param jsonReader + * @param oxmReader + */ + @Inject + public InstanceReader(JsonReader jsonReader, OxmReader oxmReader) { + this.jsonReader = jsonReader; + this.oxmReader = oxmReader; + } + + public OxmReader getOxmReader() { + return oxmReader; + } + + /** + * Gets object instance values. + * + * @param json + * a Named Query JSON payload + * @param mapping + * defines the paths that allow the extraction of values from the object instance. This includes: + *
    + *
  • origin: path that serves as the starting point for the instance search
  • + *
  • root: path to underlying instance objects that can be examined by recursively calling the + * getValues method
  • + *
+ * + * @return a {@link Multimap} of instances keyed by their model id. + * @throws ValidationServiceException + */ + public Multimap getValues(String json, ModelInstanceMapper mapping) throws ValidationServiceException { + Multimap values = HashMultimap.create(); + + DocumentContext document = jsonReader.parse(json); + + if (MappingType.RELATIONSHIP.equals(mapping.getMappingType())) { + String rootPath = mapping.getInstance().getRoot(); + if (rootPath == null || rootPath.isEmpty()) { + throw new ValidationServiceException(ValidationServiceError.INSTANCE_MAPPING_ROOT_ERROR); + } + + JsonElement jsonElement = jsonReader.getJsonElement(document, rootPath); + + if (jsonElement instanceof JsonArray) { + JsonArray jsonArray = jsonElement.getAsJsonArray(); + + processRelatedObjects(values, jsonArray); + } + } else { + // We are dealing with attributes. + String valuePath = mapping.getInstance().getValue(); + if (valuePath != null && !valuePath.isEmpty()) { + List attributes = jsonReader.get(json, valuePath); + for (String attribute : attributes) { + values.put(attribute, null); + } + } + } + + return values; + } + + /** + * Gets the instance type, e.g. connector, pserver, etc. + * + * @param json + * a Named Query JSON payload + * @return the type of the entity + */ + public String getInstanceType(String json) { + return getNamedQueryEntity(json).getEntityType(); + } + + /** + * Gets the id of the instance. Uses the {@link OxmReader} to identify the property holding the primary key.
+ * + * WARNING: Some types of object appear to have more than one primary key. This method uses the first primary key. + * + * @param json + * a Named Query JSON payload + * @return the identifier of the object instance + * @throws ValidationServiceException + */ + public String getInstanceId(String json) throws ValidationServiceException { + String instanceId = null; + + InstanceEntity entity = getNamedQueryEntity(json); + + List primaryKeys = oxmReader.getPrimaryKeys(entity.getEntityType()); + + if (primaryKeys != null && !primaryKeys.isEmpty()) { + JsonObject instance = entity.getObject().getAsJsonObject(); + JsonElement primaryKey = instance.get(primaryKeys.get(0)); + instanceId = primaryKey == null ? null : primaryKey.getAsString(); + } + + return instanceId; + } + + /** + * Strips the instance out of its payload wrapping. + * + * @param json + * a Named Query JSON payload + * @param mappings + * the definition of the paths that allow the extraction of the instance from the JSON payload + * @return + * @throws ValidationServiceException + */ + public String getInstance(String json, List mappings) throws ValidationServiceException { + String origin = mappings.iterator().next().getInstance().getOrigin(); + List jsonList = jsonReader.get(json, origin); + + if (!jsonList.isEmpty()) { + return jsonList.get(0); + } else { + throw new ValidationServiceException(ValidationServiceError.INSTANCE_READER_NO_INSTANCE, origin, json); + } + } + + /** + * Extracts the entity from a Named Query JSON payload. + * + * @param json + * a Named Query JSON payload + * @return an {@link InstanceEntity} object + */ + public InstanceEntity getNamedQueryEntity(String json) { + return getNamedQueryEntity(jsonParser.parse(json).getAsJsonObject()); + } + + /** + * Gets the model identifier of a given entity. + * + * @param entity + * a JSON entity + * @return a model identifier attribute value if the attribute exists else a null is returned. + * @throws ValidationServiceException + */ + public String getModelId(String entity) throws ValidationServiceException { + String modelId = null; + List readResult = jsonReader.get(entity, JSON_PATH_MODEL_ID); + if (!readResult.isEmpty()) { + modelId = readResult.get(0); + } + return modelId; + } + + /** + * Gets the resource version of the instance. + * + * @param json + * a Named Query JSON payload + * @return the resource version of the object instance + */ + public String getResourceVersion(String json) { + String resourceVersion = null; + + InstanceEntity entity = getNamedQueryEntity(json); + + if (entity != null && entity.getObject() != null && entity.getObject().getAsJsonObject().has(RESOURCE_VERSION)) { + resourceVersion = entity.getObject().getAsJsonObject().get(RESOURCE_VERSION).getAsString(); + } + return resourceVersion; + } + + /** + * Gets the model name of the instance. + * + * @param jsonString + * a Named Query JSON payload + * @return the model name of the object instance + * @throws ValidationServiceException + */ + public String getModelName(String jsonString) { + JsonObject jsonObject = jsonParser.parse(jsonString).getAsJsonObject(); + return getModelName(jsonObject); + } + + /** + * @param jsonObject + * @return + */ + private String getModelName(JsonObject jsonObject) { + for (Entry entry : jsonObject.entrySet()) { + if (MODEL_NAME.equals(entry.getKey())) { + return entry.getValue().getAsString(); + } + } + return null; + } + + private void processRelatedObjects(Multimap values, JsonArray jsonArray) { + for (JsonElement relatedObject : jsonArray) { + JsonObject jsonObject = relatedObject.getAsJsonObject(); + + InstanceEntity entity = getNamedQueryEntity(jsonObject); + if (entity != null) { + values.put(entity.getModelName() == null ? entity.getEntityType() : entity.getModelName(), jsonObject.toString()); + } + } + } + + private InstanceEntity getNamedQueryEntity(JsonObject jsonObject) { + Set> entrySet = jsonObject.entrySet(); + + String modelName = getModelName(jsonObject); + + for (Entry entry : entrySet) { + if (!Arrays.asList(INVALID_ENTRIES).contains(entry.getKey())) { + return new InstanceEntity(entry.getKey(), modelName, entry.getValue().getAsJsonObject(), jsonObject); + } + } + + return null; + } + + /** + * An Entity bean for the InstanceReader + * + */ + public class InstanceEntity { + + private String entityType; + private String modelName; + private JsonObject object; + private JsonObject objectAndGraph; + + /** + * @param entityType + * @param modelName + * @param object + * @param objectAndGraph + */ + public InstanceEntity(String entityType, String modelName, JsonObject object, JsonObject objectAndGraph) { + this.entityType = entityType; + this.modelName = modelName; + this.object = object; + this.objectAndGraph = objectAndGraph; + } + + public String getEntityType() { + return entityType; + } + + public String getModelName() { + return modelName; + } + + public JsonObject getObject() { + return object; + } + + public JsonObject getObjectAndGraph() { + return objectAndGraph; + } + + @Override + public String toString() { + return "Entity [entityType=" + entityType + ", modelName=" + modelName + ", object=" + object.toString() + ", fullObject=" + + objectAndGraph.toString() + "]"; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/modeldriven/validator/ModelDrivenValidator.java b/src/main/java/org/onap/aai/validation/modeldriven/validator/ModelDrivenValidator.java new file mode 100644 index 0000000..3a8ebb2 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/validator/ModelDrivenValidator.java @@ -0,0 +1,306 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven.validator; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.gson.JsonObject; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import javax.inject.Inject; +import org.apache.commons.collections.CollectionUtils; +import org.dom4j.Node; +import org.onap.aai.validation.Validator; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.modeldriven.ModelCacheManager; +import org.onap.aai.validation.modeldriven.ModelId; +import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMapper; +import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMappingReader; +import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMapper.MappingType; +import org.onap.aai.validation.reader.EntityReader; +import org.onap.aai.validation.reader.EventReader; +import org.onap.aai.validation.reader.InstanceEntityReader; +import org.onap.aai.validation.reader.data.Entity; +import org.onap.aai.validation.reader.data.EntityId; +import org.onap.aai.validation.result.ValidationResult; +import org.onap.aai.validation.result.Violation; +import org.onap.aai.validation.result.Violation.Builder; +import org.onap.aai.validation.result.Violation.ViolationType; + +/** + * Validates object instances against the ECOMP model. + * + */ +public class ModelDrivenValidator implements Validator { + + /** + * Types of validation rules. + */ + public enum RuleType { + REL, ATTR + } + + /** + * Types of validation outcomes. + */ + public enum ValidationOutcomeType { + NO_MODEL, MISSING, UNEXPECTED; + } + + private ModelCacheManager modelCacheManager; + private List mappings; + private InstanceReader instanceReader; + private EventReader eventReader; + + /** + * Constructor defining injected dependencies. + * + * @param modelCacheManager + * a cache manager for the models + * @param modelInstanceMappingReader + * a configuration reader to provide model and instance mapping + * @param instanceReader + * a reader of A&AI instances + * @param eventReader + * @throws ValidationServiceException + */ + @Inject + public ModelDrivenValidator(ModelCacheManager modelCacheManager, ModelInstanceMappingReader modelInstanceMappingReader, InstanceReader instanceReader, + EventReader eventReader) throws ValidationServiceException { + this.modelCacheManager = modelCacheManager; + this.mappings = modelInstanceMappingReader.getMappings(); + this.instanceReader = instanceReader; + this.eventReader = eventReader; + } + + @Override + public void initialise() throws ValidationServiceException { + // Deliberately empty + } + + /** + * Validates the given event instance against the ECOMP model. + * + * @param eventInstance + * the event instance to be validated + * @return {@link Violation} with the results of the object validation + * @throws ValidationServiceException + */ + @Override + public List validate(String eventInstance) throws ValidationServiceException { + // Read event json into Entity bean + Entity eventEntity = eventReader.getEntity(eventInstance); + + EntityReader reader = new InstanceEntityReader(instanceReader); + String entityJson = instanceReader.getInstance(eventEntity.getJson(), mappings); + Entity instanceEntity = new Entity(entityJson, instanceReader.getInstanceType(entityJson), eventEntity.getEntityLink(), reader); + + // Get model ID from object instance and retrieve corresponding model. + ModelId modelId = new ModelId(ModelId.ATTR_MODEL_ID, instanceReader.getModelId(instanceEntity.getJson())); + Node modelElement = modelCacheManager.get(modelId); + + List violations = new ArrayList<>(); + + if (modelElement == null) { + ViolationInfo info = ViolationInfo.valueOf(ModelDrivenValidator.ValidationOutcomeType.NO_MODEL.toString()); + Map details = new HashMap<>(); + details.put("No model ID", modelId.getModelId()); + Violation.Builder builder = new Violation.Builder(instanceEntity).violationType(ViolationType.MODEL); + builder.category(info.getCategory()).severity(info.getSeverity()).violationDetails(details) + .errorMessage(info.getErrorMessage(modelId.getModelId())); + violations.add(builder.build()); + } else { + // Validate model with instance according to mappings. + for (ModelInstanceMapper mapping : mappings) { + List currentViolations = new ArrayList<>(); + + // If we are validating related objects, find the first valid child object to begin validating from. + Node validModelElement = modelElement; + if (MappingType.RELATIONSHIP.equals(mapping.getMappingType()) && !ModelReader.isValidModelType(modelElement, mapping)) { + Multimap models = HashMultimap.create(); + ModelReader.getValuesAndModels(modelElement, mapping, modelCacheManager, models); + validModelElement = models.isEmpty() ? modelElement : models.values().iterator().next(); + } + + validateAllRecursive(validModelElement, instanceEntity, mapping, currentViolations, reader); + violations.addAll(currentViolations); + } + } + + ValidationResult validationResult = new ValidationResult(instanceEntity); + + // This is a shortcut to passing the parent model name all the way down. + populateViolationModelNames(violations, instanceEntity); + + validationResult.addViolations(violations); + + return Arrays.asList(validationResult); + } + + /* + * Recursively validates all child entities starting with the crown widget. + */ + private void validateAllRecursive(Node currentModelNode, Entity entity, ModelInstanceMapper mapping, List validations, EntityReader reader) + throws ValidationServiceException { + String entityLink = null; + Multimap modelMap = ModelReader.getValues(currentModelNode, mapping, modelCacheManager); + Multimap instanceMap = instanceReader.getValues(entity.getJson(), mapping); + + // Validate model with instance according to mappings. + // Note: Currently the cardinality of instances are not validated. + List currentViolations = validateModelInstanceValues(modelMap.keySet(), instanceMap.keySet(), entity, mapping); + validations.addAll(currentViolations); + + // Remove erroring objects from the maps so that we don't validate their children. + for (Violation currentViolation : currentViolations) { + String entityType = (String) currentViolation.getViolationDetails().get(Violation.ENTITY_TYPE_PROPERTY); + if (entityType != null) { + modelMap.removeAll(entityType); + instanceMap.removeAll(entityType); + } + } + + // Continue down the model hierarchy for objects that did not error in the current layer. + for (Entry modelEntry : modelMap.entries()) { + // Get the child model. + Node childModelNode = modelEntry.getValue(); + if (childModelNode != null) { + // Validate all child instance objects with current child model. + Collection childInstanceObjects = instanceMap.get(modelEntry.getKey()); + for (String childInstanceObject : childInstanceObjects) { + Entity childEntity = new Entity(childInstanceObject, instanceReader.getInstanceType(childInstanceObject), entityLink, reader); + validateAllRecursive(childModelNode, childEntity, mapping, validations, reader); + } + } + } + } + + /** + * Compares the List of values found in the model with the values found in the Json and generates validation errors + * based on the differences. + * + * @param modelValues + * the values found in the model + * @param instanceValues + * the values found in the Json. + * @param entity + * @param modelInstanceMapper + * the mappings used to to find the model and instance values + * @return List of Validation objects representing the errors found during validation. + * @throws ValidationServiceException + */ + private List validateModelInstanceValues(Set modelValues, Set instanceValues, Entity entity, + ModelInstanceMapper modelInstanceMapper) throws ValidationServiceException { + List violations = new ArrayList<>(); + + Collection missingValues = CollectionUtils.subtract(modelValues, instanceValues); + violations.addAll(setViolationDetails(ValidationOutcomeType.MISSING, missingValues, entity, modelInstanceMapper)); + + Collection unexpectedValues = CollectionUtils.subtract(instanceValues, modelValues); + violations.addAll(setViolationDetails(ValidationOutcomeType.UNEXPECTED, unexpectedValues, entity, modelInstanceMapper)); + + return violations; + } + + /* + * Sets the list of {@link Violation} objects with all the violation details. + * + * @param outcome + * + * @param values the values that are causing the violation + * + * @param entity the entity being validated + * + * @param modelInstanceMapper the mappings used to to find the model and instance values + * + * @return list of {@link Violation} objects set by this method + * + * @throws ValidationServiceException + */ + private List setViolationDetails(ValidationOutcomeType outcome, Collection values, Entity entity, ModelInstanceMapper modelInstanceMapper) + throws ValidationServiceException { + + List violations = new ArrayList<>(); + Builder builder = new Builder(entity).violationType("Model"); + + for (Object value : values) { + RuleType ruleType = modelInstanceMapper.getMappingType().equals(MappingType.RELATIONSHIP) ? RuleType.REL : RuleType.ATTR; + String category = outcome.toString() + "_" + ruleType; + + ViolationInfo info = ViolationInfo.valueOf(category); + builder.category(info.getCategory()); + builder.severity(info.getSeverity()); + + Map details = new HashMap<>(); + details.put(outcome.toString() + " " + ruleType.toString(), value); + + switch (ruleType) { + case ATTR: + builder.errorMessage(info.getErrorMessage(value)); + break; + case REL: + buildEntityIdDetails(details, entity); + builder.errorMessage(info.getErrorMessage(entity.getIds().toString(), entity.getType(), value)); + break; + default: + // Do nothing + break; + } + builder.violationDetails(details); + violations.add(builder.build()); + } + + return violations; + } + + /* + * Add entity IDs to the violation details + * + * @param details the violation details to populate + * + * @param entity + * + * @throws ValidationServiceException + */ + private void buildEntityIdDetails(Map details, Entity entity) throws ValidationServiceException { + JsonObject entityIdsObject = new JsonObject(); + for (EntityId entityId : entity.getIds()) { + entityIdsObject.addProperty(entityId.getPrimaryKey(), entityId.getValue()); + } + details.put(Violation.ENTITY_ID_PROPERTY, entityIdsObject); + details.put(Violation.ENTITY_TYPE_PROPERTY, entity.getType()); + details.put(Violation.ENTITY_MODELNAME_PROPERTY, instanceReader.getModelName(entity.getJson())); + } + + /* + * Sets the model name attribute on all violations in the list. The model name is retrieved from the entity + * provided. + */ + private void populateViolationModelNames(List violations, Entity entity) { + String modelName = instanceReader.getModelName(entity.getJson()); + for (Violation violation : violations) { + violation.setModelName(modelName); + } + } +} diff --git a/src/main/java/org/onap/aai/validation/modeldriven/validator/ModelReader.java b/src/main/java/org/onap/aai/validation/modeldriven/validator/ModelReader.java new file mode 100644 index 0000000..04728a3 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/validator/ModelReader.java @@ -0,0 +1,236 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven.validator; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.dom4j.Node; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.modeldriven.ModelCacheManager; +import org.onap.aai.validation.modeldriven.ModelId; +import org.onap.aai.validation.modeldriven.configuration.mapping.Filter; +import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMapper; +import org.onap.aai.validation.modeldriven.configuration.mapping.ModelInstanceMapper.MappingType; +import org.onap.aai.validation.modeldriven.parser.XMLModelParser; + +/** + * Reads values from the model. + */ +public class ModelReader { + + private static final String ATTRIBUTE_MODELTYPE = "model-type"; + + /** + * Do not instantiate an object of this class + */ + private ModelReader() { + // Deliberately empty + } + + /** + * Gets the values of a model element as defined by the model-instance mapping configuration. When the mapping + * type is "attribute", the multimap will be returned with a null value. + * + * @param modelElement + * the model element from which the values will be extracted + * @param mapping + * the model-instance mapping object defining the path to the model values + * @param modelCacheManager + * the model cache manager used to retrieve further models + * @return a {@link Multimap} of model values. + * @throws ValidationServiceException + */ + public static Multimap getValues(Node modelElement, ModelInstanceMapper mapping, ModelCacheManager modelCacheManager) + throws ValidationServiceException { + Multimap values = HashMultimap.create(); + + if (MappingType.ATTRIBUTE.equals(mapping.getMappingType())) { + // Get attributes on current model element. + Multimap modelValues = getModelValues(modelElement, mapping, false); + if (modelValues.isEmpty()) { + throw new ValidationServiceException(ValidationServiceError.MODEL_VALUE_ERROR, + mapping.getModel().getValue(), modelElement.asXML()); + } + values.putAll(modelValues); + } else { + // Get related objects. + getValuesAndModels(modelElement, mapping, modelCacheManager, values); + } + + + return values; + } + + /** + * Returns the model type property of the current model element. + * + * @param model + * The current model element. + * @return the model type of the current element or null if not found. + */ + public static String getModelType(Node model) { + String modelType = null; + List modelTypeElements = XMLModelParser.getObjectsFromXPath(model, ATTRIBUTE_MODELTYPE); + if (!modelTypeElements.isEmpty()) { + modelType = modelTypeElements.iterator().next().getText(); + } + return modelType; + } + + /** + * @param model + * @param mapping + * @return True if supplied model is of type widget. + */ + public static boolean isValidModelType(Node model, ModelInstanceMapper mapping) { + Collection validTypes = mapping.getModel().getFilter().getValid(); + return validTypes.isEmpty() ? false :validTypes.contains(getModelType(model)); + } + + /** + * Populates a Multimap of models. If a root and filter are defined in the mapping it will navigate the model to find a + * valid models according to the filter. If the root property is not defined a model is not returned. + * + * @param model + * the model to be inspected + * @param mapping + * the model-instance mapping object defining the root model + * @param modelCacheManager + * the model cache manager used to retrieve further models + * @param models + * a Multimap of models that will be populated with further models + * @throws ValidationServiceException + */ + public static void getValuesAndModels(Node model, ModelInstanceMapper mapping, ModelCacheManager modelCacheManager, Multimap models) throws ValidationServiceException { + String root = mapping.getModel().getRoot(); + + if (root == null) { + return; + } + + List childModelElements = XMLModelParser.getObjectsFromXPath(model, root); + for (Node childModel : childModelElements) { + // If the child element is a leaf, this could either mean the end of the hierarchy, or that we have + // encountered a resource and need to retrieve a separate model to continue the model traversal. + List modelNames = getModelValuesList(childModel, mapping); + if (!hasChildren(childModel, root) && !isValidModel(childModel, mapping) && mapping.getModel().getId() != null) { + childModel = getChildModelNode(modelCacheManager, childModel, mapping); + } + + if (isValidModel(childModel, mapping)) { + for (String modelName : modelNames) { + models.put(modelName, childModel); + } + } else { + getValuesAndModels(childModel, mapping, modelCacheManager, models); + } + } + } + + /** + * Find the next child model given a specific node. + * + * @param modelCacheManager + * the model cache manager used to retrieve further models + * @param node + * the top-level node under which child model nodes are searched + * @param rootXPath + * the path expression to apply to the node to find child elements + * @param modelIdPath + * the path expression to apply to the node to find the child model IDs + * @return either or the {@code node} if there were no matches for {@code id} + * @throws ValidationServiceException + */ + private static Node getChildModelNode(ModelCacheManager modelCacheManager, Node node, ModelInstanceMapper mapping) throws ValidationServiceException { + Node childModel = node; + + // Get the model for the specified node to check its type. + // Only one model ID is expected, although the API returns a list. + List childModelIds = XMLModelParser.getObjectsFromXPath(node, mapping.getModel().getId()); + + if (!childModelIds.isEmpty()) { + // Found the child model ID, so retrieve the child model from cache. + ModelId modelId = new ModelId(ModelId.ATTR_MODEL_NAME_VERSION_ID, childModelIds.iterator().next().getText()); + Node fullChildModel = modelCacheManager.get(modelId); + + if (fullChildModel != null && !isValidModelType(fullChildModel, mapping)) { + // Child model is not a widget so replace current child model with the full child model + // retrieved from the cache. + List fullChildModelElements = XMLModelParser.getObjectsFromXPath(fullChildModel, mapping.getModel().getRoot()); + // Only one crown widget is expected, although the API returns a list. + childModel = fullChildModelElements.isEmpty() ? node : fullChildModelElements.iterator().next(); + } + } + + return childModel; + } + + private static Multimap getModelValues(Node model, ModelInstanceMapper mapping, boolean addModel) { + Multimap values = HashMultimap.create(); + List valueStrings = getModelValuesList(model, mapping); + for (String value : valueStrings) { + values.put(value, addModel ? model : null); + } + return values; + } + + private static List getModelValuesList(Node model, ModelInstanceMapper mapping) { + List values = new ArrayList<>(); + List valueElements = XMLModelParser.getObjectsFromXPath(model, mapping.getModel().getValue()); + for (Node node : valueElements) { + values.add(node.getText()); + } + return values; + } + + private static boolean isValidModel(Node node, ModelInstanceMapper mapping) { + Filter filter = mapping.getModel().getFilter(); + if (filter == null) { + return true; + } + + List valid = filter.getValid(); + // If there are no valid values, return false. + if (valid.isEmpty()) { + return false; + } + + String filterXPath = filter.getPath(); + if (filterXPath == null) { + return false; + } + + List filterNodes = XMLModelParser.getObjectsFromXPath(node, filterXPath); + for (Node filterNode : filterNodes) { + String text = filterNode.getText(); + if (valid.contains(text)) { + return true; + } + } + + return false; + } + + private static boolean hasChildren(Node parent, String rootXPath) { + return !XMLModelParser.getObjectsFromXPath(parent, rootXPath).isEmpty(); + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/modeldriven/validator/ViolationInfo.java b/src/main/java/org/onap/aai/validation/modeldriven/validator/ViolationInfo.java new file mode 100644 index 0000000..e452d73 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/modeldriven/validator/ViolationInfo.java @@ -0,0 +1,88 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.modeldriven.validator; + +import java.text.MessageFormat; +import org.onap.aai.validation.controller.ValidationController; + +/** + * Defines and formats the violation information. + */ +public enum ViolationInfo { + //@formatter:off + NO_MODEL ("NO_MODEL", ValidationController.VALIDATION_ERROR_SEVERITY, "No model ID=[{0}]", "The model [{0}] could not be found"), + MISSING_ATTR ("MISSING_ATTR", ValidationController.VALIDATION_ERROR_SEVERITY, "{0} {1}=[{2}]", "Attribute [{0}] is missing in the object instance"), + UNEXPECTED_ATTR ("UNEXPECTED_ATTR", ValidationController.VALIDATION_ERROR_SEVERITY, "{0} {1}=[{2}]", "Attribute [{0}] should not be present in the object instance"), + MISSING_REL ("MISSING_REL", ValidationController.VALIDATION_ERROR_SEVERITY, "entityId=[{0}] entityType=[{1}], {2} {3}=[{4}]", "Entity {0} of type [{1}] must be related to [{2}]"), + UNEXPECTED_REL ("UNEXPECTED_REL", ValidationController.VALIDATION_ERROR_SEVERITY, "entityId=[{0}] entityType=[{1}], {2} {3}=[{4}]", "Entity {0} of type [{1}] must not be related to [{2}]"); + //@formatter:on + + private String category; + private String severity; + private String violationDetails; + private String errorMessage; + + /** + * @param category + * @param severity + * @param violationDetails + * @param errorMessage + */ + private ViolationInfo(String category, String severity, String violationDetails, String errorMessage) { + this.category = category; + this.severity = severity; + this.violationDetails = violationDetails; + this.errorMessage = errorMessage; + } + + /** + * @return + */ + public String getCategory() { + return this.category; + } + + /** + * @return + */ + public String getSeverity() { + return this.severity; + } + + /** + * @param args + * @return + */ + public String getViolationDetails(Object... args) { + return formatter(this.violationDetails, args); + } + + /** + * @param args + * @return + */ + public String getErrorMessage(Object... args) { + return formatter(this.errorMessage, args); + } + + private String formatter(String violationInfo, Object... args) { + MessageFormat formatter = new MessageFormat(""); + formatter.applyPattern(violationInfo); + return formatter.format(args); + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/publisher/MessagePublisher.java b/src/main/java/org/onap/aai/validation/publisher/MessagePublisher.java new file mode 100644 index 0000000..94e1f29 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/publisher/MessagePublisher.java @@ -0,0 +1,47 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.publisher; + +import java.util.Collection; +import org.onap.aai.validation.exception.ValidationServiceException; + +/** + * A Publisher of messages. + * + */ +public interface MessagePublisher { + + /** + * Sends a message somewhere. + * + * @param message + * The String message to send. + * @throws ValidationServiceException + */ + void publishMessage(String message) throws ValidationServiceException; + + /** + * Sends a Collection of messages somewhere. + * + * @param messages + * The String messages to send. + * @throws ValidationServiceException + */ + void publishMessages(Collection messages) throws ValidationServiceException; + +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/publisher/ValidationEventPublisher.java b/src/main/java/org/onap/aai/validation/publisher/ValidationEventPublisher.java new file mode 100644 index 0000000..0cebbf9 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/publisher/ValidationEventPublisher.java @@ -0,0 +1,164 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.publisher; + +import org.onap.aai.event.client.DMaaPEventPublisher; +import org.onap.aai.validation.config.TopicAdminConfig; +import org.onap.aai.validation.config.TopicConfig; +import org.onap.aai.validation.config.TopicConfig.Topic; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.factory.DMaaPEventPublisherFactory; +import org.onap.aai.validation.logging.ApplicationMsgs; +import org.onap.aai.validation.logging.LogHelper; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import javax.inject.Inject; + +/** + * Event Publisher + * + */ +public class ValidationEventPublisher implements MessagePublisher { + + private static LogHelper applicationLogger = LogHelper.INSTANCE; + + private List publisherTopics; + + private boolean enablePublishing; + + private long retries; + + private long retriesRemaining; + + private DMaaPEventPublisherFactory dMaapFactory; + + + /** + * Instantiates an Event Publisher instance using properties from config file. + * + * @param topicConfig + * @param topicAdminConfig + */ + @Inject + public ValidationEventPublisher(TopicConfig topicConfig, TopicAdminConfig topicAdminConfig) { + enablePublishing = topicAdminConfig.isPublishEnable(); + if (enablePublishing) { + publisherTopics = topicConfig.getPublisherTopics(); + retries = topicAdminConfig.getPublishRetries(); + } + dMaapFactory = new DMaaPEventPublisherFactory(); + } + + /** + * Connect to the event publisher, add the message, and then publish it by closing the publisher. + */ + @Override + public void publishMessage(String message) throws ValidationServiceException { + Collection messages = new ArrayList<>(); + messages.add(message); + publishMessages(messages); + } + + /** + * Connect to the event publisher, adds the messages, and then publish them by closing the publisher. + */ + @Override + public void publishMessages(Collection messages) throws ValidationServiceException { + if (!enablePublishing) { + return; + } else { + applicationLogger.debug("Publishing messages: " + messages); + for (Topic topic : publisherTopics) { + retriesRemaining = retries; + publishMessages(messages, topic); + } + } + } + + private void publishMessages(Collection messages, Topic topic) throws ValidationServiceException { + + DMaaPEventPublisher dMaapEventPublisher = dMaapFactory.createEventPublisher(topic.getHost(), topic.getName(), topic.getUsername(), + topic.getPassword(), topic.getTransportType()); + + try { + // Add our message to the publisher's queue/bus + int result = dMaapEventPublisher.sendSync(topic.getPartition(), messages); + if (result != messages.size()) { + applicationLogger.warn(ApplicationMsgs.UNSENT_MESSAGE_WARN); + closeEventPublisher(dMaapEventPublisher); + retryOrThrow(messages, topic, new ValidationServiceException( + ValidationServiceError.EVENT_CLIENT_INCORRECT_NUMBER_OF_MESSAGES_SENT, result)); + } + } catch (Exception e) { + applicationLogger.error(ApplicationMsgs.UNSENT_MESSAGE_ERROR); + closeEventPublisher(dMaapEventPublisher); + retryOrThrow(messages, topic, + new ValidationServiceException(ValidationServiceError.EVENT_CLIENT_SEND_ERROR, e)); + } + + completeMessageSending(dMaapEventPublisher, topic); + } + + /** + * Publish the queued messages by closing the publisher. + * + * @param eventPublisher the publisher to close + * @throws AuditException + */ + private void completeMessageSending(DMaaPEventPublisher eventPublisher, Topic topic) + throws ValidationServiceException { + List unsentMsgs = closeEventPublisher(eventPublisher); + + if (unsentMsgs != null && !unsentMsgs.isEmpty()) { + // Log the error, as the exception will not be propagated due to the fact that the Cambria Client throws + // an exception first in a separate thread. + applicationLogger.error(ApplicationMsgs.EVENT_CLIENT_CLOSE_UNSENT_MESSAGE, + ValidationServiceError.EVENT_CLIENT_CLOSE_UNSENT_MESSAGE.getMessage(unsentMsgs)); + + retryOrThrow(unsentMsgs, topic, new ValidationServiceException( + ValidationServiceError.EVENT_CLIENT_CLOSE_UNSENT_MESSAGE, unsentMsgs)); + } + } + + private void retryOrThrow(Collection messages, Topic topic, ValidationServiceException exceptionToThrow) + throws ValidationServiceException { + if (retriesRemaining <= 0) { + applicationLogger.warn(ApplicationMsgs.SEND_MESSAGE_ABORT_WARN); + throw exceptionToThrow; + } else { + applicationLogger.warn(ApplicationMsgs.SEND_MESSAGE_RETRY_WARN); + retriesRemaining--; + publishMessages(messages, topic); + } + } + + private List closeEventPublisher(DMaaPEventPublisher eventPublisher) throws ValidationServiceException { + try { + return eventPublisher.closeWithUnsent(); + } catch (Exception e) { + throw new ValidationServiceException(ValidationServiceError.EVENT_CLIENT_CLOSE_ERROR, e); + } + } + + public void setEventPublisherFactory(DMaaPEventPublisherFactory dMaapFactory) { + this.dMaapFactory = dMaapFactory; + } + +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/reader/EntityReader.java b/src/main/java/org/onap/aai/validation/reader/EntityReader.java new file mode 100644 index 0000000..f55af2f --- /dev/null +++ b/src/main/java/org/onap/aai/validation/reader/EntityReader.java @@ -0,0 +1,61 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.reader; + +import java.util.List; +import java.util.Optional; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.reader.data.EntityId; + +/** + * Interface for extracting values from an entity (in JSON format). + * + */ +public interface EntityReader { + + /** + * Return the value found at the supplied path. + * + * @param json + * the JSON representation of the entity + * @param path + * specifier of the path to the value within the JSON entity + * @return either a primitive object (e.g. String, Integer) or a JSON element + * @throws ValidationServiceException + */ + Object getObject(String json, String path) throws ValidationServiceException; + + /** + * @param json + * the JSON representation of the entity + * @param type + * the type of the entity + * @return the key value(s) identifying the entity + * @throws ValidationServiceException + */ + List getIds(String json, String type) throws ValidationServiceException; + + /** + * @param json + * the JSON representation of the entity + * @return the resource version of the entity (if present) + * @throws ValidationServiceException + */ + Optional getResourceVersion(String json) throws ValidationServiceException; + +} diff --git a/src/main/java/org/onap/aai/validation/reader/EventEntityReader.java b/src/main/java/org/onap/aai/validation/reader/EventEntityReader.java new file mode 100644 index 0000000..7f285f8 --- /dev/null +++ b/src/main/java/org/onap/aai/validation/reader/EventEntityReader.java @@ -0,0 +1,118 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.reader; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.onap.aai.validation.config.EventReaderConfig; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.reader.data.EntityId; + +/** + * An entity reader for reading A&AI events. This implementation is used by the EventReader + * + */ +public class EventEntityReader implements EntityReader { + + private JsonReader jsonReader; + private OxmReader oxmReader; + + private EventReaderConfig config; + + /** + * @param eventReaderConfig + * @param jsonReader + * @param oxmReader + */ + public EventEntityReader(final EventReaderConfig eventReaderConfig, final JsonReader jsonReader, + final OxmReader oxmReader) { + this.jsonReader = jsonReader; + this.oxmReader = oxmReader; + this.config = eventReaderConfig; + } + + /** + * Parse the supplied json and return the content (values) specified by the supplied path + * + * @param json + * @param path + * @return either a String or an Array of objects + * @throws ValidationServiceException + */ + @Override + public Object getObject(String json, String path) throws ValidationServiceException { + return jsonReader.getObject(jsonReader.parse(json), path); + } + + public String getEntityResourceVersionPath() { + return config.getEntityResourceVersionPath(); + } + + @Override + public List getIds(String json, String type) throws ValidationServiceException { + List ids = new ArrayList<>(); + for (String pk : oxmReader.getPrimaryKeys(type)) { + String pkPaths = config.getEntityIdPath(pk); + String pkValue = getPropertyForMultiplePaths(json, pkPaths).orElseThrow( + () -> new ValidationServiceException(ValidationServiceError.EVENT_READER_MISSING_PROPERTY, + pkPaths)); + ids.add(new EntityId(pk, pkValue)); + } + return ids; + } + + /** + * Get an entity property from an entity in JSON format. + * + * @param json the entity + * @param path the JSON path to the property + * @return an optional property value + * @throws ValidationServiceException + */ + public Optional getProperty(String json, String path) throws ValidationServiceException { + return jsonReader.get(json, path).stream().findFirst(); + } + + @Override + public Optional getResourceVersion(String json) throws ValidationServiceException { + return getPropertyForMultiplePaths(json, getEntityResourceVersionPath()); + } + + /** + * Takes a comma separated list of jsonpaths and applies each one in turn until a value is found. + * + * @param json The json to search + * @param multiplePaths Comma separated list of jsonpath strings + * @return The value of the first jsonpath string that returns a value + * @throws ValidationServiceException + */ + private Optional getPropertyForMultiplePaths(String json, String multiplePaths) + throws ValidationServiceException { + Optional propertyValue = Optional.empty(); + for (String path : multiplePaths.split(",")) { + propertyValue = getProperty(json, path); + if (propertyValue.isPresent()) { + break; + } + } + return propertyValue; + } + +} diff --git a/src/main/java/org/onap/aai/validation/reader/EventReader.java b/src/main/java/org/onap/aai/validation/reader/EventReader.java new file mode 100644 index 0000000..614ccbf --- /dev/null +++ b/src/main/java/org/onap/aai/validation/reader/EventReader.java @@ -0,0 +1,215 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.reader; + +import com.jayway.jsonpath.DocumentContext; +import java.util.List; +import java.util.Optional; +import org.onap.aai.validation.config.EventReaderConfig; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.reader.data.Entity; +import org.onap.aai.validation.util.StringUtils; + +/** + * Reads event objects. + * + */ +public class EventReader { + + private EventReaderConfig eventReaderConfig; + + private JsonReader jsonReader; + + private EntityReader entityReader; + + /** + * + * @param eventReaderConfig the event reader configuration including paths to event properties + * @param jsonReader a JSON reader + * @param oxmReader an OXM reader to retrieve the primary key names for the entity + */ + public EventReader(final EventReaderConfig eventReaderConfig, final JsonReader jsonReader, + final OxmReader oxmReader) { + this.eventReaderConfig = eventReaderConfig; + this.jsonReader = jsonReader; + this.entityReader = new EventEntityReader(eventReaderConfig, jsonReader, oxmReader); + } + + /////////////////////////////////////////////////////////////////////////// + // PUBLIC METHODS + /////////////////////////////////////////////////////////////////////////// + + /** + * Get the domain of the event. + * + * @param event a JSON String with the event contents + * @return the domain of the event + * @throws ValidationServiceException + */ + public Optional getEventDomain(String event) throws ValidationServiceException { + List readerResult = jsonReader.get(event, eventReaderConfig.getEventDomainPath()); + return getFirst(readerResult); + } + + /** + * Get the action of the event. + * + * @param event a JSON String with the event contents + * @return the action of the event + * @throws ValidationServiceException + */ + public Optional getEventAction(String event) throws ValidationServiceException { + List readerResult = jsonReader.get(event, eventReaderConfig.getEventActionPath()); + return getFirst(readerResult); + } + + /** + * Get the type of the event. + * + * @param event a JSON String with the event contents + * @return the type of the event + * @throws ValidationServiceException + */ + public Optional getEventType(String event) throws ValidationServiceException { + List readerResult = jsonReader.get(event, eventReaderConfig.getEventTypePath()); + return getFirst(readerResult); + } + + /** + * Get the entity type of the entity in the event. + * + * @param event a JSON String with the event contents + * @return the type of the entity + * @throws ValidationServiceException + */ + public Optional getEntityType(String event) throws ValidationServiceException { + List readerResult = jsonReader.get(event, eventReaderConfig.getEntityTypePath()); + return getFirst(readerResult); + } + + /** + * Get the entity contained in the event. + * + * @param event a JSON String with the event contents + * @return the entity + */ + public Entity getEntity(String event) throws ValidationServiceException { + DocumentContext document = jsonReader.parse(event); + + String entityType = getValue(document, eventReaderConfig.getEntityTypePath()) + .orElseThrow(() -> new ValidationServiceException(ValidationServiceError.EVENT_READER_MISSING_PROPERTY, + eventReaderConfig.getEntityTypePath())); + String topEntityType = getValue(document, eventReaderConfig.getTopEntityTypePath()).orElse(entityType); + String entityLink = getEntityLink(document); + String json = findEntity(event, topEntityType, entityType); + + return new Entity(json, entityType, entityLink, entityReader); + } + + /** + * Get the value of the JSON property defined by the path. + * + * @param json a JSON string + * @param path the path to a property + * @return the value + * @throws ValidationServiceException if the value is not present + */ + public String getValue(final String json, final String path) throws ValidationServiceException { + return getFirst(jsonReader.get(json, path)).orElseThrow( + () -> new ValidationServiceException(ValidationServiceError.EVENT_READER_MISSING_PROPERTY, path)); + } + + /////////////////////////////////////////////////////////////////////////// + // PRIVATE METHODS + /////////////////////////////////////////////////////////////////////////// + + private String findEntity(String event, String topEntityType, String entityType) throws ValidationServiceException { + String json; + if (entityType.equals(topEntityType)) { + json = getValue(event, eventReaderConfig.getEntityPath()); + } else { + json = findNestedEntity(event, eventReaderConfig.getNestedEntityPath(entityType)); + } + return json; + } + + /** + * @param event + * @param path + * @return + * @throws ValidationServiceException + */ + private String findNestedEntity(String event, String path) throws ValidationServiceException { + List entities = jsonReader.get(event, path); + if (entities.isEmpty()) { + throw new ValidationServiceException(ValidationServiceError.EVENT_READER_MISSING_PROPERTY, path); + } else if (entities.size() > 1) { + throw new ValidationServiceException(ValidationServiceError.EVENT_READER_TOO_MANY_ENTITIES); + } + return entities.get(0); + } + + private Optional getFirst(List l) { + return l.stream().findFirst(); + } + + private Optional getValue(final DocumentContext document, final String path) { + return getFirst(jsonReader.getAsList(document, path)); + } + + /** + * Gets the entity link from the event but altered by stripping a prefix identified by a delimiter configured in the + * event reader properties configuration. + * + * @param document the parsed JSON event + * @return the entity link + * @throws ValidationServiceException + */ + private String getEntityLink(DocumentContext document) throws ValidationServiceException { + String entityLink = getValue(document, eventReaderConfig.getEntityLinkPath()).orElse(""); + String strippedEntityLink = null; + try { + strippedEntityLink = StringUtils.stripPrefixRegex(entityLink, eventReaderConfig.getEntityLinkDelimiter()); + } catch (ValidationServiceException e) { + throw new ValidationServiceException(ValidationServiceError.EVENT_READER_PROPERTY_READ_ERROR, e); + } + return strippedEntityLink; + } + + /////////////////////////////////////////////////////////////////////////// + // GETTERS AND SETTERS + /////////////////////////////////////////////////////////////////////////// + + /** + * + * @return event configuration + */ + public EventReaderConfig getEventReaderConfig() { + return eventReaderConfig; + } + + /** + * + * @param eventReaderConfig event configuration + */ + public void setEventReaderConfig(EventReaderConfig eventReaderConfig) { + this.eventReaderConfig = eventReaderConfig; + } + +} diff --git a/src/main/java/org/onap/aai/validation/reader/InstanceEntityReader.java b/src/main/java/org/onap/aai/validation/reader/InstanceEntityReader.java new file mode 100644 index 0000000..0b9fbed --- /dev/null +++ b/src/main/java/org/onap/aai/validation/reader/InstanceEntityReader.java @@ -0,0 +1,75 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.reader; + +import com.google.gson.JsonElement; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; +import org.onap.aai.validation.modeldriven.validator.InstanceReader; +import org.onap.aai.validation.modeldriven.validator.InstanceReader.InstanceEntity; +import org.onap.aai.validation.reader.data.EntityId; + +/** + * Entity reader implemented using the model-driven instance reader. + * + */ +public class InstanceEntityReader implements EntityReader { + + private InstanceReader reader; + + /** + * @param instanceReader + */ + public InstanceEntityReader(InstanceReader instanceReader) { + this.reader = instanceReader; + } + + @Override + public Object getObject(String json, String attribute) throws ValidationServiceException { + throw new ValidationServiceException(ValidationServiceError.INSTANCE_READER_NO_INSTANCE, "Not implemented"); + } + + @Override + public List getIds(String json, String type) throws ValidationServiceException { + List ids = new ArrayList<>(); + + InstanceEntity entity = reader.getNamedQueryEntity(json); + + List primaryKeys = reader.getOxmReader().getPrimaryKeys(entity.getEntityType()); + + if (primaryKeys != null && !primaryKeys.isEmpty()) { + for (String pk : primaryKeys) { + JsonElement jsonValue = entity.getObject().getAsJsonObject().get(pk); + if (jsonValue != null) { + ids.add(new EntityId(pk, jsonValue.getAsString())); + } + } + } + + return ids; + } + + @Override + public Optional getResourceVersion(String json) throws ValidationServiceException { + return Optional.of(reader.getResourceVersion(json)); + } + +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/validation/reader/JsonReader.java b/src/main/java/org/onap/aai/validation/reader/JsonReader.java new file mode 100644 index 0000000..9d349ac --- /dev/null +++ b/src/main/java/org/onap/aai/validation/reader/JsonReader.java @@ -0,0 +1,186 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.aai.validation.reader; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.Option; +import com.jayway.jsonpath.ReadContext; +import com.jayway.jsonpath.spi.json.GsonJsonProvider; +import com.jayway.jsonpath.spi.json.JsonProvider; +import com.jayway.jsonpath.spi.mapper.GsonMappingProvider; +import com.jayway.jsonpath.spi.mapper.MappingProvider; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import org.onap.aai.validation.exception.ValidationServiceError; +import org.onap.aai.validation.exception.ValidationServiceException; + +/** + * Reads JSON objects. Supported by the JayWay JsonPath library. + */ +public class JsonReader { + + private Configuration jsonPathConfig; + + /** + * Initialise the JSON reader. + */ + public JsonReader() { + setJsonProvider(); + this.jsonPathConfig = Configuration.builder().options(Option.SUPPRESS_EXCEPTIONS).build(); + } + + /** + * Parse the JSON. + * + * @param json + * the JSON object + * @return a {@link ReadContext} the parsed JSON. + * @throws ValidationServiceException + */ + public DocumentContext parse(String json) throws ValidationServiceException { + DocumentContext document = null; + try { + document = JsonPath.using(jsonPathConfig).parse(json); + } catch (Exception e) { + throw new ValidationServiceException(ValidationServiceError.JSON_READER_PARSE_ERROR, e); + } + return document; + } + + /** + * Gets values from JSON objects. + * + * @param json + * the JSON object + * @param path + * the path to property values. The format must comply with the JayWay JsonPath definition. + * @return a List of values found by evaluating the path. + * @throws ValidationServiceException + */ + public List get(String json, String path) throws ValidationServiceException { + return getAsList(parse(json), path); + } + + /** + * Gets values from JSON objects. Used in combination with {@link JsonReader#parse(String)} it reduces the number of + * times the JSON document is parsed. + * + * @param document + * a {@link DocumentContext} object with the parsed JSON + * @param path + * the path to property values. The format must comply with the JayWay JsonPath definition. + * @return a List of values found by evaluating the path, or an empty list if no values were found + */ + public List getAsList(DocumentContext document, String path) { + List result = new ArrayList<>(); + JsonElement jsonElement = document.read(path); + if (jsonElement != null) { + if (jsonElement.isJsonPrimitive()) { + result.add(jsonElement.getAsString()); + } else if (jsonElement.isJsonObject()) { + result.add(jsonElement.getAsJsonObject().toString()); + } else if (jsonElement.isJsonArray()) { + for (JsonElement obj : jsonElement.getAsJsonArray()) { + Object object = jsonElementToObject(obj); + result.add(object == null ? null : object.toString()); + } + } + } + return result; + } + + /** + * Get the value(s) from the specified JSON document + * + * @param document + * a {@link DocumentContext} object with the parsed JSON + * @param path + * the path to property value(s). The format must comply with the JayWay JsonPath definition. + * @return either all the values found by evaluating the path (e.g. as an array), or a String object (only) where + * the path evaluates to a single primitive value + */ + public Object getObject(DocumentContext document, String path) { + return jsonElementToObject(document.read(path)); + } + + /** + * Convert the JSON element to a String or Array where possible, otherwise return the JSON object. + * + * @param jsonElement + * @return the jsonElement converted to a Java Object + */ + private Object jsonElementToObject(JsonElement jsonElement) { + if (jsonElement == null) { + return null; + } else if (jsonElement.isJsonPrimitive()) { + return jsonElement.getAsString(); + } else if (jsonElement.isJsonObject()) { + return jsonElement.getAsJsonObject(); + } else if (jsonElement.isJsonArray()) { + // Convert to a List for simplified handling within rules + return jsonArrayToList(jsonElement.getAsJsonArray()); + } else { + return jsonElement; + } + } + + private List jsonArrayToList(JsonArray jsonArray) { + List result = new ArrayList<>(); + for (JsonElement obj : jsonArray) { + result.add(jsonElementToObject(obj)); + } + return result; + } + + /** + * @param document + * @param path + * @return a JsonElement from the document + */ + public JsonElement getJsonElement(DocumentContext document, String path) { + return document.read(path); + } + + private void setJsonProvider() { + Configuration.setDefaults(new Configuration.Defaults() { + private final JsonProvider jsonProvider = new GsonJsonProvider(); + private final MappingProvider mappingProvider = new GsonMappingProvider(); + + @Override + public JsonProvider jsonProvider() { + return jsonProvider; + } + + @Override + public MappingProvider mappingProvider() { + return mappingProvider; + } + + @Override + public Set