From 2e2f969676ab391fba2198cbaa55e9b85d50216f Mon Sep 17 00:00:00 2001 From: Phillip Leigh Date: Mon, 28 Oct 2019 15:55:40 -0400 Subject: [AAI-2404]add aai-schema-abstraction library Signed-off-by: Phillip Leigh Issue-ID: AAI-2404 Change-Id: I30d954bcdf1cf020191028160610defb8dbc8ff6 --- .../java/org/onap/aai/schemaif/SchemaProvider.java | 97 + .../onap/aai/schemaif/SchemaProviderException.java | 47 + .../org/onap/aai/schemaif/SchemaProviderMsgs.java | 37 + .../onap/aai/schemaif/definitions/EdgeSchema.java | 116 + .../aai/schemaif/definitions/PropertySchema.java | 100 + .../aai/schemaif/definitions/VertexSchema.java | 65 + .../definitions/types/BooleanDataType.java | 38 + .../definitions/types/ComplexDataType.java | 58 + .../aai/schemaif/definitions/types/DataType.java | 53 + .../schemaif/definitions/types/FloatDataType.java | 43 + .../schemaif/definitions/types/IntDataType.java | 54 + .../schemaif/definitions/types/ListDataType.java | 45 + .../schemaif/definitions/types/LongDataType.java | 43 + .../schemaif/definitions/types/MapDataType.java | 45 + .../schemaif/definitions/types/StringDataType.java | 35 + .../onap/aai/schemaif/json/FromJsonEdgeSchema.java | 82 + .../aai/schemaif/json/FromJsonPropertySchema.java | 116 + .../aai/schemaif/json/FromJsonVertexSchema.java | 132 + .../onap/aai/schemaif/json/JsonSchemaProvider.java | 235 + .../schemaif/json/JsonSchemaProviderConfig.java | 58 + .../org/onap/aai/schemaif/json/SchemaInstance.java | 121 + .../aai/schemaif/json/SchemaServiceResponse.java | 67 + .../json/SecureClientHttpRequestFactory.java | 126 + .../json/definitions/DataTypeDefinition.java | 125 + .../schemaif/json/definitions/JsonEdgeSchema.java | 135 + .../json/definitions/JsonPropertySchema.java | 192 + .../aai/schemaif/json/definitions/JsonSchema.java | 167 + .../json/definitions/JsonVertexSchema.java | 141 + .../aai/schemaif/oxm/EdgePropsConfiguration.java | 42 + .../onap/aai/schemaif/oxm/FromOxmEdgeSchema.java | 75 + .../aai/schemaif/oxm/FromOxmPropertySchema.java | 141 + .../onap/aai/schemaif/oxm/FromOxmVertexSchema.java | 95 + .../onap/aai/schemaif/oxm/OxmEdgeRulesLoader.java | 246 + .../org/onap/aai/schemaif/oxm/OxmSchemaLoader.java | 236 + .../onap/aai/schemaif/oxm/OxmSchemaProvider.java | 117 + .../onap/aai/schemaif/oxm/RelationshipSchema.java | 189 + .../logging/SchemaProviderMsgs.properties | 16 + .../aai/schemaif/json/JsonSchemaProviderTest.java | 600 ++ .../aai/schemaif/oxm/OxmSchemaProviderTest.java | 254 + .../aai/schemaif/oxm/OxmSchemaServiceSetup.java | 78 + .../src/test/resources/json/badEdgeSchema.json | 100 + .../src/test/resources/json/badPropSchema.json | 101 + .../src/test/resources/json/badTypeSchema.json | 101 + .../src/test/resources/json/badVertexSchema.json | 100 + .../src/test/resources/json/jsonSchema.json | 976 +++ .../test/resources/json/schemaServiceResponse.json | 131 + .../oxm/edge-props/edge_properties_v13.json | 6 + .../oxm/edge-rules/v13/DbEdgeRules_v13.json | 2848 ++++++++ .../src/test/resources/oxm/oxm/v13/aai_oxm_v13.xml | 6775 ++++++++++++++++++++ 49 files changed, 15800 insertions(+) create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProvider.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProviderException.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProviderMsgs.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/EdgeSchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/PropertySchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/VertexSchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/BooleanDataType.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/ComplexDataType.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/DataType.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/FloatDataType.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/IntDataType.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/ListDataType.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/LongDataType.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/MapDataType.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/StringDataType.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonEdgeSchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonPropertySchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonVertexSchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/JsonSchemaProvider.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/JsonSchemaProviderConfig.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaInstance.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaServiceResponse.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SecureClientHttpRequestFactory.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/DataTypeDefinition.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonEdgeSchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonPropertySchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonSchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonVertexSchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/EdgePropsConfiguration.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmEdgeSchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmPropertySchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmVertexSchema.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmEdgeRulesLoader.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaLoader.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaProvider.java create mode 100644 aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/RelationshipSchema.java create mode 100644 aai-schema-abstraction/src/main/resources/logging/SchemaProviderMsgs.properties create mode 100644 aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/json/JsonSchemaProviderTest.java create mode 100644 aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/oxm/OxmSchemaProviderTest.java create mode 100644 aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/oxm/OxmSchemaServiceSetup.java create mode 100644 aai-schema-abstraction/src/test/resources/json/badEdgeSchema.json create mode 100644 aai-schema-abstraction/src/test/resources/json/badPropSchema.json create mode 100644 aai-schema-abstraction/src/test/resources/json/badTypeSchema.json create mode 100644 aai-schema-abstraction/src/test/resources/json/badVertexSchema.json create mode 100644 aai-schema-abstraction/src/test/resources/json/jsonSchema.json create mode 100644 aai-schema-abstraction/src/test/resources/json/schemaServiceResponse.json create mode 100644 aai-schema-abstraction/src/test/resources/oxm/edge-props/edge_properties_v13.json create mode 100644 aai-schema-abstraction/src/test/resources/oxm/edge-rules/v13/DbEdgeRules_v13.json create mode 100644 aai-schema-abstraction/src/test/resources/oxm/oxm/v13/aai_oxm_v13.xml (limited to 'aai-schema-abstraction/src') diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProvider.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProvider.java new file mode 100644 index 00000000..1e798196 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProvider.java @@ -0,0 +1,97 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.onap.aai.schemaif.definitions.EdgeSchema; +import org.onap.aai.schemaif.definitions.VertexSchema; + +public interface SchemaProvider { + + /** + * Load the schema into memory + */ + public void loadSchema() throws SchemaProviderException; + + /** + * Get the identifier for the more recent version of the schema + * + * @return The schema version identifier + */ + public String getLatestSchemaVersion() throws SchemaProviderException; + + /** + * Get the schema definition for a vertex + * + * @param vertexName - Name of the vertex + * @param schemaVersion - Version of the schema to use + * + * @return The vertex schema definition + */ + public VertexSchema getVertexSchema(String vertexName, String schemaVersion) throws SchemaProviderException; + + /** + * Get the schema definition for an edge + * + * @param edgeType - Type of the edge + * @param sourceVertex - The source vertex for the edge + * @param targetVertex - The target vertex for the edge + * @param schemaVersion - Version of the schema to use + * + * @return The edge schema definition + */ + public EdgeSchema getEdgeSchema(String edgeType, String sourceVertex, String targetVertex, String version) throws SchemaProviderException; + + /** + * Get the list of edge definitions which are adjacent to the given vertex + * + * @param vertexType - Type of the vertex + * @param schemaVersion - Version of the schema to use + * + * @return The list of edge schema definitions + */ + public Set getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException; + + /** + * Get the list of edge definitions which are valid for the given source and target + * + * @param sourceType - Type of the source vertex + * @param targetType - Type of the target vertex + * @param schemaVersion - Version of the schema to use + * + * @return The list of edge schema definitions + */ + public Set getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version) throws SchemaProviderException; + + /** + * Get vertex map for a schema version + * + * @param schemaVersion - Version of the schema to use + * + * @return The list of vertex types + */ + public Map getVertexMap(String schemaVersion) throws SchemaProviderException; + + } diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProviderException.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProviderException.java new file mode 100644 index 00000000..9a95c337 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProviderException.java @@ -0,0 +1,47 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif; + + +public class SchemaProviderException extends Exception { + + private static final long serialVersionUID = 8162385108397238865L; + + + public SchemaProviderException() {} + + public SchemaProviderException(String message) { + super(message); + } + + public SchemaProviderException(Throwable cause) { + super(cause); + } + + public SchemaProviderException(String message, Throwable cause) { + super(message, cause); + } + + public SchemaProviderException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProviderMsgs.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProviderMsgs.java new file mode 100644 index 00000000..9b2c1518 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProviderMsgs.java @@ -0,0 +1,37 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.onap.aai.schemaif; + +import com.att.eelf.i18n.EELFResourceManager; +import org.onap.aai.cl.eelf.LogMessageEnum; + +public enum SchemaProviderMsgs implements LogMessageEnum { + SCHEMA_LOAD_ERROR, + LOADED_SCHEMA_FILE, + LOADED_DB_RULE_FILE; + + static { + EELFResourceManager.loadMessageBundle("logging/SchemaProviderMsgs"); + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/EdgeSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/EdgeSchema.java new file mode 100644 index 00000000..07dd65d1 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/EdgeSchema.java @@ -0,0 +1,116 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions; + +import java.util.Map; + + +public class EdgeSchema { + protected String name; + protected String source; + protected String target; + protected Multiplicity multiplicity; + protected Map annotations; + protected Map properties; + + public enum Multiplicity { + MANY_2_MANY, + MANY_2_ONE, + ONE_2_MANY, + ONE_2_ONE + } + + public String getName() { + return name; + } + + public String getSource() { + return source; + } + + public String getTarget() { + return target; + } + + public Multiplicity getMultiplicity() { + return multiplicity; + } + + public PropertySchema getPropertySchema(String propName) { + return properties.get(propName.toLowerCase()); + } + + public Map getPropertySchemaList() { + return properties; + } + + public String getAnnotationValue(String annotation) { + return annotations.get(annotation.toLowerCase()); + } + + public Map getAnnotations() { + return annotations; + } + + @Override + public int hashCode() { + String key = source + target + name; + return key.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (getClass() != obj.getClass()) { + return false; + } + + EdgeSchema other = (EdgeSchema) obj; + + if ( (!source.equals(other.getSource())) || (!target.equals(other.getTarget())) || (!name.equals(other.getName())) ) { + return false; + } + + return true; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("edge: " + getSource() + " -> " + getTarget() + "\n"); + sb.append(" type: " + getName() + "\n"); + sb.append(" multiplicity: " + getMultiplicity() + "\n"); + + sb.append(" annotations: " + "\n"); + for (String annotation : annotations.keySet()) { + sb.append(" " + annotation + ": " + annotations.get(annotation) + "\n"); + } + sb.append(" properties: " + "\n"); + for (PropertySchema attrSchema : getPropertySchemaList().values()) { + sb.append(attrSchema.toString()); + } + + return sb.toString(); + } + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/PropertySchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/PropertySchema.java new file mode 100644 index 00000000..a512da0b --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/PropertySchema.java @@ -0,0 +1,100 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions; + +import java.util.Map; + +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.types.DataType; + + +public class PropertySchema { + protected String name; + protected DataType dataType; + protected Boolean required; + protected String defaultValue; + protected Boolean unique; + protected Boolean isReserved; + protected Map annotations; + + public String getName() { + return name; + } + + public DataType getDataType() { + return dataType; + } + + public Boolean isRequired() { + return required; + } + + public Boolean isKey() { + return (unique && required); + } + + public Boolean isUnique() { + return unique; + } + + public String getDefaultValue() { + return defaultValue; + } + + public Boolean isReserved() { + return isReserved; + } + + public String getAnnotationValue(String annotation) { + return annotations.get(annotation.toLowerCase()); + } + + public Map getAnnotations() { + return annotations; + } + + public Object validateValue(String value) throws SchemaProviderException { + Object obj = dataType.validateValue(value); + if (obj == null) { + throw new SchemaProviderException("Invalid value for porperty '" + name + "': " + value); + } + + return obj; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(" property: " + getName() + "\n"); + sb.append(" datatype: " + dataType.toString() + "\n"); + sb.append(" required: " + isRequired() + "\n"); + sb.append(" key: " + isKey() + "\n"); + sb.append(" reserved: " + isReserved() + "\n"); + sb.append(" default: " + getDefaultValue() + "\n"); + sb.append(" annotations: " + "\n"); + + for (String annotation : annotations.keySet()) { + sb.append(" " + annotation + ": " + annotations.get(annotation) + "\n"); + } + + return sb.toString(); + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/VertexSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/VertexSchema.java new file mode 100644 index 00000000..7ad1cfc6 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/VertexSchema.java @@ -0,0 +1,65 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions; + +import java.util.Map; + + +public class VertexSchema { + protected String name; + protected Map properties; + protected Map annotations; + + public String getName() { + return name; + } + + public PropertySchema getPropertySchema(String propName) { + return properties.get(propName.toLowerCase()); + } + + public Map getPropertySchemaList() { + return properties; + } + + public Map getAnnotationSchemaList() { + return annotations; + } + + public String getAnnotationValue(String annotation) { + return annotations.get(annotation.toLowerCase()); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("vertex: " + getName() + "\n"); + sb.append(" annotations: " + "\n"); + for (String annotation : annotations.keySet()) { + sb.append(" " + annotation + ": " + annotations.get(annotation) + "\n"); + } + sb.append(" properties: " + "\n"); + for (PropertySchema attrSchema : getPropertySchemaList().values()) { + sb.append(attrSchema.toString()); + } + + return sb.toString(); + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/BooleanDataType.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/BooleanDataType.java new file mode 100644 index 00000000..52fb4ca5 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/BooleanDataType.java @@ -0,0 +1,38 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions.types; + + +public class BooleanDataType extends DataType { + public BooleanDataType() { + super(Type.BOOL); + } + + @Override + public Object validateValue(String value) { + if (value.equalsIgnoreCase("true") || (value.equalsIgnoreCase("false"))) { + return Boolean.parseBoolean(value); + } + + return null; + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/ComplexDataType.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/ComplexDataType.java new file mode 100644 index 00000000..e09c18fd --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/ComplexDataType.java @@ -0,0 +1,58 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions.types; + +import java.util.List; + +import org.onap.aai.schemaif.definitions.PropertySchema; + +public class ComplexDataType extends DataType { + private List subProperties; + + public ComplexDataType(List subProperties) { + super(Type.COMPLEX); + this.subProperties = subProperties; + } + + public List getSubProperties() { + return subProperties; + } + + @Override + public Object validateValue(String value) { + // TODO: Validate the complex type against the subProperties + return value; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("COMPLEX[ "); + + for (PropertySchema prop : getSubProperties()) { + sb.append(prop.getDataType().toString() + " "); + } + + sb.append("]"); + + return sb.toString(); + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/DataType.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/DataType.java new file mode 100644 index 00000000..a0586037 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/DataType.java @@ -0,0 +1,53 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions.types; + +import org.onap.aai.schemaif.SchemaProviderException; + +public abstract class DataType { + public enum Type { + STRING, + BOOL, + INT, + LONG, + FLOAT, + LIST, + MAP, + COMPLEX + } + + private Type type; + + public DataType(Type type) { + this.type = type; + } + + public Type getType() { + return type; + } + + public abstract Object validateValue(String value); + + public String toString() { + return getType().toString(); + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/FloatDataType.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/FloatDataType.java new file mode 100644 index 00000000..17fb9485 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/FloatDataType.java @@ -0,0 +1,43 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions.types; + +public class FloatDataType extends DataType { + public FloatDataType() { + super(Type.FLOAT); + } + + @Override + public Object validateValue(String value) { + // TODO: In Tosca, you can impose constraints such as min/max value. + // In future we can add this type of validation + Float floatValue; + try { + floatValue = Float.parseFloat(value); + } + catch (NumberFormatException e) { + return null; + } + + return floatValue; + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/IntDataType.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/IntDataType.java new file mode 100644 index 00000000..59eb788f --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/IntDataType.java @@ -0,0 +1,54 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions.types; + +import java.text.DecimalFormat; + +public class IntDataType extends DataType { + public IntDataType() { + super(Type.INT); + } + + @Override + public Object validateValue(String value) { + // TODO: In Tosca, you can impose constraints such as min/max value. + // In future we can add this type of validation + Integer intValue; + try { + intValue = Integer.parseInt(value); + } + catch (NumberFormatException e) { + // There is an edge case where an int value is stored as "x.0" in champ. + // In that case, we just want to drop the ".0" and treat it as a proper + // integer + try { + DecimalFormat decimalFormat = new DecimalFormat("0.#"); + intValue = Integer.parseInt(decimalFormat.format(Double.valueOf(value))); + } + catch (Exception ex) { + return null; + } + } + + return intValue; + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/ListDataType.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/ListDataType.java new file mode 100644 index 00000000..84adefec --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/ListDataType.java @@ -0,0 +1,45 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions.types; + +public class ListDataType extends DataType { + private DataType listType; + + public ListDataType(DataType listType) { + super(Type.LIST); + this.listType = listType; + } + + public DataType getListType() { + return listType; + } + + @Override + public Object validateValue(String value) { + // TODO: Break the string into a list and validate each element against the listType + return value; + } + + public String toString() { + return "LIST[" + listType.toString() + "]"; + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/LongDataType.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/LongDataType.java new file mode 100644 index 00000000..38195f9c --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/LongDataType.java @@ -0,0 +1,43 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions.types; + +public class LongDataType extends DataType { + public LongDataType() { + super(Type.LONG); + } + + @Override + public Object validateValue(String value) { + // TODO: In Tosca, you can impose constraints such as min/max value. + // In future we can add this type of validation + Long longInt; + try { + longInt = Long.parseLong(value); + } + catch (NumberFormatException e) { + return null; + } + + return longInt; + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/MapDataType.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/MapDataType.java new file mode 100644 index 00000000..443f460e --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/MapDataType.java @@ -0,0 +1,45 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions.types; + +public class MapDataType extends DataType { + private DataType mapType; + + public MapDataType(DataType mapType) { + super(Type.MAP); + this.mapType = mapType; + } + + public DataType getMapType() { + return mapType; + } + + @Override + public Object validateValue(String value) { + // TODO: Break the string into a map and validate each element against the mapType + return value; + } + + public String toString() { + return "MAP[" + mapType.toString() + "]"; + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/StringDataType.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/StringDataType.java new file mode 100644 index 00000000..39487ea2 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/StringDataType.java @@ -0,0 +1,35 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.definitions.types; + +public class StringDataType extends DataType { + public StringDataType() { + super(Type.STRING); + } + + @Override + public Object validateValue(String value) { + // TODO: In Tosca, you can impose constraints such as string length, regex matches, valid values, + // string length maximums, etc. In future we can add this type of validation + return value; + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonEdgeSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonEdgeSchema.java new file mode 100644 index 00000000..e3bc450b --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonEdgeSchema.java @@ -0,0 +1,82 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json; + +import java.util.HashMap; +import java.util.Map; + +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.EdgeSchema; +import org.onap.aai.schemaif.definitions.PropertySchema; +import org.onap.aai.schemaif.json.definitions.JsonEdgeSchema; + +public class FromJsonEdgeSchema extends EdgeSchema { + public static final String WILDCARD_CHAR = "*"; + + public FromJsonEdgeSchema() { + } + + public FromJsonEdgeSchema(EdgeSchema other) { + // A shallow copy should suffice, as edge definitions don't change. + name = other.getName(); + source = other.getSource(); + target = other.getTarget(); + multiplicity = other.getMultiplicity(); + properties = other.getPropertySchemaList(); + annotations = other.getAnnotations(); + } + + public void fromJson(JsonEdgeSchema jsonEdge) throws SchemaProviderException { + + name = jsonEdge.getLabel(); + source = jsonEdge.getFrom(); + target = jsonEdge.getTo(); + + // TODO: At present, multiplicity isn't described in the JSON schema. By default, make everything + // many-to-many + multiplicity = Multiplicity.MANY_2_MANY; + + // Populate annotation schema + annotations = new HashMap(); + if (jsonEdge.getAnnotations() != null) { + for (Map.Entry entry : jsonEdge.getAnnotations().entrySet()) { + annotations.put(entry.getKey().toLowerCase(), entry.getValue()); + } + } + + // Currently edge properties are not supported in the json schema + properties = new HashMap(); + } + + public void replaceWildcard(String vertexName) throws SchemaProviderException { + if (source.equals(WILDCARD_CHAR) && target.equals(WILDCARD_CHAR)) { + throw new SchemaProviderException("Edge definition with wildcard source and target: " + toString()); + } + + if (source.equals(WILDCARD_CHAR)) { + source = vertexName; + } + + if (target.equals(WILDCARD_CHAR)) { + target = vertexName; + } + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonPropertySchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonPropertySchema.java new file mode 100644 index 00000000..ea522191 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonPropertySchema.java @@ -0,0 +1,116 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.PropertySchema; +import org.onap.aai.schemaif.definitions.types.BooleanDataType; +import org.onap.aai.schemaif.definitions.types.ComplexDataType; +import org.onap.aai.schemaif.definitions.types.DataType; +import org.onap.aai.schemaif.definitions.types.IntDataType; +import org.onap.aai.schemaif.definitions.types.ListDataType; +import org.onap.aai.schemaif.definitions.types.LongDataType; +import org.onap.aai.schemaif.definitions.types.MapDataType; +import org.onap.aai.schemaif.definitions.types.StringDataType; +import org.onap.aai.schemaif.json.definitions.DataTypeDefinition; +import org.onap.aai.schemaif.json.definitions.JsonPropertySchema; + +public class FromJsonPropertySchema extends PropertySchema { + + public void fromJson(JsonPropertySchema pSchema, boolean reserved, List dataTypes) throws SchemaProviderException { + name = pSchema.getName(); + defaultValue = pSchema.getDefaultValue() == null ? "" : pSchema.getDefaultValue(); + required = pSchema.getRequired() == null ? false : pSchema.getRequired(); + unique = pSchema.getUnique() == null ? false : pSchema.getUnique(); + isReserved = reserved; + dataType = resolveDataType(pSchema.getDataType(), dataTypes); + + // Populate annotations + annotations = new HashMap(); + if (pSchema.getAnnotations() != null) { + for (Map.Entry entry : pSchema.getAnnotations().entrySet()) { + annotations.put(entry.getKey().toLowerCase(), entry.getValue()); + } + } + } + + private DataType resolveDataType(String typeString, List dataTypes) throws SchemaProviderException { + if (typeString.equalsIgnoreCase("string")) { + return new StringDataType(); + } + + if (typeString.equalsIgnoreCase("integer")) { + return new IntDataType(); + } + + if (typeString.equalsIgnoreCase("long")) { + return new LongDataType(); + } + + if (typeString.equalsIgnoreCase("boolean")) { + return new BooleanDataType(); + } + + if (typeString.startsWith("list:")) { + String segments[] = typeString.split(":"); + DataType subType = resolveDataType(segments[1], dataTypes); + return new ListDataType(subType); + } + + if (typeString.startsWith("map:")) { + String segments[] = typeString.split(":"); + DataType subType = resolveDataType(segments[1], dataTypes); + return new MapDataType(subType); + } + + // Must be a complex type + return resolveComplexDataType(typeString, dataTypes); + } + + private DataType resolveComplexDataType(String typeString, List dataTypes) throws SchemaProviderException { + // It must be a custom/complex type. + DataTypeDefinition dType = null; + for (DataTypeDefinition d : dataTypes) { + if ( (d.getName().equals(typeString)) ) { + dType = d; + break; + } + } + + if (dType == null) { + throw new SchemaProviderException("Invalid data type: " + typeString); + } + + List propList = new ArrayList(); + for (JsonPropertySchema p : dType.getProperties()) { + FromJsonPropertySchema pSchema = new FromJsonPropertySchema(); + pSchema.fromJson(p, false, dataTypes); + propList.add(pSchema); + } + + return new ComplexDataType(propList); + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonVertexSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonVertexSchema.java new file mode 100644 index 00000000..7a3251f1 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonVertexSchema.java @@ -0,0 +1,132 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.PropertySchema; +import org.onap.aai.schemaif.definitions.VertexSchema; +import org.onap.aai.schemaif.json.definitions.DataTypeDefinition; +import org.onap.aai.schemaif.json.definitions.JsonPropertySchema; +import org.onap.aai.schemaif.json.definitions.JsonVertexSchema; + + +public class FromJsonVertexSchema extends VertexSchema { + public void fromJson(JsonVertexSchema jsonVertex, List dataTypes, List commonProps) throws SchemaProviderException { + name = jsonVertex.getName(); + properties = new HashMap(); + annotations = new HashMap(); + + // Populate property schema + if (jsonVertex.getProperties() != null) { + for (JsonPropertySchema pSchema : jsonVertex.getProperties()) { + FromJsonPropertySchema propSchema = new FromJsonPropertySchema(); + propSchema.fromJson(pSchema, false, dataTypes); + properties.put(propSchema.getName().toLowerCase(), propSchema); + } + } + + // Add common properties + if (commonProps != null) { + for (JsonPropertySchema pSchema : commonProps) { + FromJsonPropertySchema propSchema = new FromJsonPropertySchema(); + propSchema.fromJson(pSchema, true, dataTypes); + properties.put(propSchema.getName().toLowerCase(), propSchema); + } + } + else { + // TODO: This is a hack until the schema-service return the list of common props + addCommonProps(); + } + + // Populate annotation schema + if (jsonVertex.getAnnotations() != null) { + for (Map.Entry entry : jsonVertex.getAnnotations().entrySet()) { + annotations.put(entry.getKey().toLowerCase(), entry.getValue()); + } + } + + // The searchable and indexed annotations, need to grab these from the property annotations + // and store them at the vertex level as well (backwards compatibility with OXM) + StringBuilder searchableVal = new StringBuilder(); + StringBuilder indexedVal = new StringBuilder(); + for (PropertySchema pSchema : properties.values()) { + if ( (pSchema.getAnnotationValue("searchable") != null) + && (pSchema.getAnnotationValue("searchable").equalsIgnoreCase("true")) ) { + if (searchableVal.length() > 0) { + searchableVal.append(","); + } + searchableVal.append(pSchema.getName()); + } + if ( (pSchema.getAnnotationValue("indexed") != null) + && (pSchema.getAnnotationValue("indexed").equalsIgnoreCase("true")) ) { + if (indexedVal.length() > 0) { + indexedVal.append(","); + } + indexedVal.append(pSchema.getName()); + } + } + + if (searchableVal.length() > 0) { + annotations.put("searchable", searchableVal.toString()); + } + if (indexedVal.length() > 0) { + annotations.put("indexedprops", indexedVal.toString()); + } + } + + private void addCommonProps() throws SchemaProviderException { + addCommonProperty("aai-uuid", false, true, "string", "true"); + addCommonProperty("last-mod-source-of-truth", false, false, "string", "false"); + addCommonProperty("aai-node-type", false, false, "string", "false"); + addCommonProperty("aai-created-ts", false, false, "string", "false"); + addCommonProperty("aai-unique-key", false, false, "string", "false"); + addCommonProperty("aai-last-mod-ts", false, false, "string", "false"); + addCommonProperty("source-of-truth", false, false, "string", "false"); + addCommonProperty("aai-uri", false, false, "string", "false"); + + } + + private void addCommonProperty(String name, boolean req, boolean unique, String type, String indexed) throws SchemaProviderException { + JsonPropertySchema pSchema = new JsonPropertySchema(); + pSchema.setName(name); + pSchema.setRequired(req); + pSchema.setUnique(unique); + pSchema.setDataType(type); + pSchema.setDescription(""); + pSchema.setDefaultValue(""); + + Map propAnnotations = new HashMap(); + propAnnotations.put("indexed", indexed); + propAnnotations.put("searchable", "false"); + propAnnotations.put("source_of_truth_type", "AAI"); + + pSchema.setAnnotations(propAnnotations); + + FromJsonPropertySchema propSchema = new FromJsonPropertySchema(); + propSchema.fromJson(pSchema, true, null); + + properties.put(name, propSchema); + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/JsonSchemaProvider.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/JsonSchemaProvider.java new file mode 100644 index 00000000..a947eac4 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/JsonSchemaProvider.java @@ -0,0 +1,235 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Scanner; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.schemaif.SchemaProvider; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.SchemaProviderMsgs; +import org.onap.aai.schemaif.definitions.EdgeSchema; +import org.onap.aai.schemaif.definitions.VertexSchema; +import org.onap.aai.schemaif.json.definitions.JsonEdgeSchema; +import org.onap.aai.schemaif.json.definitions.JsonSchema; +import org.onap.aai.schemaif.json.definitions.JsonVertexSchema; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + + +public class JsonSchemaProvider implements SchemaProvider { + Logger logger = LoggerFactory.getInstance().getLogger(JsonSchemaProvider.class.getName()); + + private JsonSchemaProviderConfig config; + private Map schemaCache = new ConcurrentHashMap<>(); + private RestTemplate restTemplate = null; + + public JsonSchemaProvider(JsonSchemaProviderConfig config) { + this.config = config; + + SecureClientHttpRequestFactory fac = new SecureClientHttpRequestFactory(config); + fac.setBufferRequestBody(false); + this.restTemplate = new RestTemplate(fac); + } + + @Override + public void loadSchema() throws SchemaProviderException { + // Load the latest schema version + fetchSchemaVersion(getLatestSchemaVersion()); + } + + @Override + public String getLatestSchemaVersion() throws SchemaProviderException { + return "v0"; + } + + @Override + public VertexSchema getVertexSchema(String vertexName, String schemaVersion) throws SchemaProviderException { + SchemaInstance inst = getSchemaVersion(schemaVersion); + return inst.getVertexSchema(vertexName); + } + + @Override + public EdgeSchema getEdgeSchema(String edgeType, String sourceVertex, String targetVertex, String version) + throws SchemaProviderException { + SchemaInstance inst = getSchemaVersion(version); + return inst.getEdgeSchema(sourceVertex, targetVertex, edgeType); + } + + @Override + public Set getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException { + SchemaInstance inst = getSchemaVersion(version); + + Set edgeList = inst.getEdgeSchema(vertexType); + if (edgeList == null) { + edgeList = new HashSet(); + } + + return edgeList; + } + + @Override + public Set getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version) + throws SchemaProviderException { + SchemaInstance inst = getSchemaVersion(version); + + if (inst == null) { + throw new SchemaProviderException("Unable to find schema version " + version); + } + + Set edgeList = inst.getEdgeSchemas(sourceType, targetType); + if (edgeList == null) { + edgeList = new HashSet(); + } + + return edgeList; + } + + public void loadSchema(String payload, String version) throws SchemaProviderException { + JsonSchema jsonSchema = JsonSchema.fromJson(payload); + SchemaInstance schemaInst = new SchemaInstance(); + + for (JsonVertexSchema jsonVertex : jsonSchema.getNodeTypes()) { + FromJsonVertexSchema vSchema = new FromJsonVertexSchema(); + vSchema.fromJson(jsonVertex, jsonSchema.getDataTypes(), jsonSchema.getCommonProperties()); + schemaInst.addVertex(vSchema); + } + + for (JsonEdgeSchema jsonEdge : jsonSchema.getRelationshipTypes()) { + FromJsonEdgeSchema eSchema = new FromJsonEdgeSchema(); + eSchema.fromJson(jsonEdge); + schemaInst.addEdge(eSchema); + } + + schemaCache.put(version, schemaInst); + } + + private synchronized void fetchSchemaVersion(String version) throws SchemaProviderException { + if (schemaCache.get(version) != null) { + return; + } + + + String url = config.getSchemaServiceBaseUrl() + "/" + version; + + HttpHeaders headers = new HttpHeaders(); + headers.put("X-FromAppId", Arrays.asList(config.getServiceName())); + headers.put("X-TransactionId", Arrays.asList(java.util.UUID.randomUUID().toString())); + headers.setAccept(Arrays.asList(org.springframework.http.MediaType.APPLICATION_OCTET_STREAM)); + + HttpEntity entity = new HttpEntity(headers); + + ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, entity, byte[].class); + + + if (response.getStatusCodeValue() == HttpStatus.NOT_FOUND.value()) { + logger.warn(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "version " + version + " not found"); + throw new SchemaProviderException("Schema version " + version + " not found"); + } + else if (response.getStatusCodeValue() != HttpStatus.OK.value()) { + logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "failed to load version " + version + ": " + response.getBody()); + throw new SchemaProviderException("Error getting schema version " + version + ":" + response.getBody()); + } + + try { + SchemaServiceResponse resp = SchemaServiceResponse.fromJson(unzipAndGetJSONString(response)); + loadSchema(resp.getData().toJson(), version); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "failed to load version " + version + ": " + + response.getBody() + "\n" + writer.toString()); + throw new SchemaProviderException("Error loading schema version " + version + ":" + ex.getMessage()); + + } + + logger.info(SchemaProviderMsgs.LOADED_SCHEMA_FILE, version); + } + + private String unzipAndGetJSONString(ResponseEntity response) throws IOException { + StringBuffer sb = new StringBuffer(""); + + ZipInputStream zipStream = null; + try { + + zipStream = new ZipInputStream(new ByteArrayInputStream(response.getBody())); + ZipEntry entry = null; + while ((entry = zipStream.getNextEntry()) != null) { + Scanner sc = new Scanner(zipStream); + while (sc.hasNextLine()) { + sb.append(sc.nextLine()); + } + + } + } finally { + try { + zipStream.closeEntry(); + zipStream.close(); + } catch (Exception e) { + logger.warn(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, e.toString()); + + } + } + + return sb.toString(); + } + + private SchemaInstance getSchemaVersion(String version) throws SchemaProviderException { + // TODO: For now, we are only supporting a single version of the schema. Load that + // version regardless of what the client asks for. + String versionToLoad = getLatestSchemaVersion(); + SchemaInstance inst = schemaCache.get(versionToLoad); + + if (inst == null) { + fetchSchemaVersion(versionToLoad); + inst = schemaCache.get(versionToLoad); + if (inst == null) { + throw new SchemaProviderException("Unable to find schema version " + versionToLoad); + } + } + + return inst; + } + + @Override + public Map getVertexMap(String schemaVersion) throws SchemaProviderException { + return getSchemaVersion(schemaVersion).getVertexMap(); + } + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/JsonSchemaProviderConfig.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/JsonSchemaProviderConfig.java new file mode 100644 index 00000000..3a235f63 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/JsonSchemaProviderConfig.java @@ -0,0 +1,58 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json; + + +public class JsonSchemaProviderConfig { + + private String schemaServiceBaseUrl; + private String schemaServiceCertFile; + private String schemaServiceCertPwd; + private String serviceName; + + public String getSchemaServiceBaseUrl() { + return schemaServiceBaseUrl; + } + public void setSchemaServiceBaseUrl(String schemaServiceBaseUrl) { + this.schemaServiceBaseUrl = schemaServiceBaseUrl; + } + + public String getSchemaServiceCertFile() { + return schemaServiceCertFile; + } + public void setSchemaServiceCertFile(String schemaServiceCertFile) { + this.schemaServiceCertFile = schemaServiceCertFile; + } + + public String getSchemaServiceCertPwd() { + return schemaServiceCertPwd; + } + public void setSchemaServiceCertPwd(String schemaServiceCertPwd) { + this.schemaServiceCertPwd = schemaServiceCertPwd; + } + + public String getServiceName() { + return serviceName; + } + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaInstance.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaInstance.java new file mode 100644 index 00000000..77a1c56b --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaInstance.java @@ -0,0 +1,121 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.EdgeSchema; +import org.onap.aai.schemaif.definitions.VertexSchema; + +public class SchemaInstance { + // vertex-name -> vertex-schema + private Map vertexMap = new HashMap<>(); + + // source:target:type -> edge-schema + private Map edgeKeyMap = new HashMap<>(); + + // source:target -> edge-schema + private Map> edgeSourceTargetMap = new HashMap<>(); + + // vertex-name -> edge-schema + private Map> vertexEdgeMap = new HashMap<>(); + + public VertexSchema getVertexSchema(String vertexName) { + return vertexMap.get(vertexName.toLowerCase()); + } + + public EdgeSchema getEdgeSchema(String source, String target, String type) { + return edgeKeyMap.get(generateEdgeKey(source, target, type)); + } + + public Set getEdgeSchemas(String source, String target) { + return edgeSourceTargetMap.get(source.toLowerCase() + ":" + target.toLowerCase()); + } + + public Set getEdgeSchema(String vertexName) { + return vertexEdgeMap.get(vertexName.toLowerCase()); + } + + public void addVertex(VertexSchema v) { + vertexMap.put(v.getName().toLowerCase(), v); + } + + public void addEdge(EdgeSchema e) throws SchemaProviderException { + if (e.getSource().equals(FromJsonEdgeSchema.WILDCARD_CHAR) || + e.getTarget().equals(FromJsonEdgeSchema.WILDCARD_CHAR)) { + // Handle wildcard edges + for (VertexSchema vertex : vertexMap.values()) { + addWildcardEdge(e, vertex); + } + } + else { + addEdgeInternal(e); + } + } + + private void addWildcardEdge(EdgeSchema e, VertexSchema vertex) throws SchemaProviderException { + FromJsonEdgeSchema newEdge = new FromJsonEdgeSchema(e); + newEdge.replaceWildcard(vertex.getName()); + addEdgeInternal(newEdge); + } + + private void addEdgeInternal(EdgeSchema e) { + edgeKeyMap.put(generateEdgeKey(e.getSource(), e.getTarget(), e.getName()), e); + + Set edgeListSource = vertexEdgeMap.get(e.getSource().toLowerCase()); + Set edgeListTarget = vertexEdgeMap.get(e.getTarget().toLowerCase()); + + if (edgeListSource == null) { + edgeListSource = new HashSet(); + } + if (edgeListTarget == null) { + edgeListTarget = new HashSet(); + } + + edgeListSource.add(e); + edgeListTarget.add(e); + vertexEdgeMap.put(e.getSource().toLowerCase(), edgeListSource); + vertexEdgeMap.put(e.getTarget().toLowerCase(), edgeListTarget); + + String sourceTargetKey = e.getSource().toLowerCase() + ":" + e.getTarget().toLowerCase(); + Set edgeList = edgeSourceTargetMap.get(sourceTargetKey); + if (edgeList == null) { + edgeList = new HashSet(); + } + + edgeList.add(e); + edgeSourceTargetMap.put(sourceTargetKey, edgeList); + } + + private String generateEdgeKey(String source, String target, String type) { + String key = source + ":" + target + ":" + type; + return key.toLowerCase(); + } + + public Map getVertexMap() { + return vertexMap; + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaServiceResponse.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaServiceResponse.java new file mode 100644 index 00000000..7fa123a5 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaServiceResponse.java @@ -0,0 +1,67 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json; + +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.json.definitions.JsonSchema; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; + +public class SchemaServiceResponse { + public static final String SCHEMA_TYPE_OXM = "oxm"; + public static final String SCHEMA_TYPE_JSON = "json"; + + private static final Gson gson = new GsonBuilder().create(); + + @SerializedName("schema-version") + private String version; + + @SerializedName("schema-content") + private JsonSchema data; + + public String getVersion() { + return version; + } + + public JsonSchema getData() { + return data; + } + + public String toJson() { + return gson.toJson(this); + } + + public static SchemaServiceResponse fromJson(String json) throws SchemaProviderException { + try { + if (json == null || json.isEmpty()) { + throw new SchemaProviderException("Empty schema-service response"); + } + + return gson.fromJson(json, SchemaServiceResponse.class); + } catch (Exception ex) { + throw new SchemaProviderException("Invalid response from schema service: " + ex.getMessage()); + } + } + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SecureClientHttpRequestFactory.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SecureClientHttpRequestFactory.java new file mode 100644 index 00000000..0b48a36c --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SecureClientHttpRequestFactory.java @@ -0,0 +1,126 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR 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.schemaif.json; + + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.security.KeyStore; +import java.security.cert.X509Certificate; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.springframework.http.client.SimpleClientHttpRequestFactory; + + +public class SecureClientHttpRequestFactory extends SimpleClientHttpRequestFactory { + + private static final String SSL_PROTOCOL = "TLS"; + private static final String KEYSTORE_ALGORITHM = "SunX509"; + private static final String KEYSTORE_TYPE = "PKCS12"; + private JsonSchemaProviderConfig config; + + + public SecureClientHttpRequestFactory(JsonSchemaProviderConfig config) { + super(); + this.config = config; + } + + @Override + protected void prepareConnection(final HttpURLConnection connection, final String httpMethod) + throws IOException { + if (connection instanceof HttpsURLConnection) { + ((HttpsURLConnection) connection) + .setSSLSocketFactory(getSSLContext().getSocketFactory()); + ((HttpsURLConnection) connection).setHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String str, SSLSession sslSession) { + return true; + } + }); + } else { + + throw new IOException(); + } + super.prepareConnection(connection, httpMethod); + } + + protected SSLContext getSSLContext() throws IOException { + try { + TrustManager[] trustAllCerts = null; + + // We aren't validating certificates, so create a trust manager that + // does + // not validate certificate chains. + trustAllCerts = new TrustManager[] {new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + }}; + + SSLContext ctx = SSLContext.getInstance(SSL_PROTOCOL); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEYSTORE_ALGORITHM); + KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE); + + char[] pwd = null; + if (config.getSchemaServiceCertPwd()!= null) { + pwd = config.getSchemaServiceCertPwd().toCharArray(); + } + + if (config.getSchemaServiceCertFile() != null) { + FileInputStream fin =null; + try { + fin = new FileInputStream(config.getSchemaServiceCertFile()); + + // Load the keystore and initialize the key manager factory. + ks.load(fin, pwd); + kmf.init(ks, pwd); + + ctx.init(kmf.getKeyManagers(), trustAllCerts, null); + }finally { + fin.close(); + } + } else { + ctx.init(null, trustAllCerts, null); + } + + return ctx; + } catch (Exception e) { + throw new IOException("Problem with getting the SSL Context::" + e.getMessage(), e); + } + + } + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/DataTypeDefinition.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/DataTypeDefinition.java new file mode 100644 index 00000000..93c67bdc --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/DataTypeDefinition.java @@ -0,0 +1,125 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json.definitions; + +import java.util.List; + +import org.onap.aai.schemaif.SchemaProviderException; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class DataTypeDefinition { + private static final Gson gson = new GsonBuilder().create(); + + private String name; + private String description; + private List properties; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public void validate() throws SchemaProviderException { + if ( (getName() == null) || (getName().isEmpty()) ) { + throw new SchemaProviderException("Type definition missing a name"); + } + + if (getProperties() != null) { + for (JsonPropertySchema propSchema : getProperties()) { + propSchema.validate(); + } + } + } + + public String toJson() { + return gson.toJson(this); + } + + public static DataTypeDefinition fromJson(String json) { + return gson.fromJson(json, DataTypeDefinition.class); + } + + @Override + public String toString() { + return "DataTypeDefinition [name=" + name + ", description=" + description + ", properties=" + + properties + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((properties == null) ? 0 : properties.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DataTypeDefinition other = (DataTypeDefinition) obj; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (properties == null) { + if (other.properties != null) + return false; + } else if (!properties.equals(other.properties)) + return false; + return true; + } + + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonEdgeSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonEdgeSchema.java new file mode 100644 index 00000000..ffbc54de --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonEdgeSchema.java @@ -0,0 +1,135 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json.definitions; + + +import java.util.Map; + +import org.onap.aai.schemaif.SchemaProviderException; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class JsonEdgeSchema { + private static final Gson gson = new GsonBuilder().create(); + + private String from; + private String to; + private String label; + private Map annotations; + + public String getFrom() { + return from; + } + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + public void setTo(String to) { + this.to = to; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public Map getAnnotations() { + return annotations; + } + public void setAnnotations(Map annotations) { + this.annotations = annotations; + } + + public void validate() throws SchemaProviderException { + if ( (getTo() == null) || (getTo().isEmpty()) ) { + throw new SchemaProviderException("Edge definition missing 'to'"); + } + + if ( (getFrom() == null) || (getFrom().isEmpty()) ) { + throw new SchemaProviderException("Edge definition missing 'from'"); + } + + if ( (getLabel() == null) || (getLabel().isEmpty()) ) { + throw new SchemaProviderException("Edge definition missing 'label'"); + } + } + + public String toJson() { + return gson.toJson(this); + } + + public static JsonEdgeSchema fromJson(String json) { + return gson.fromJson(json, JsonEdgeSchema.class); + } + @Override + public String toString() { + return "JsonEdgeSchema [from=" + from + ", to=" + to + ", label=" + label + ", annotations=" + + annotations + "]"; + } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((annotations == null) ? 0 : annotations.hashCode()); + result = prime * result + ((from == null) ? 0 : from.hashCode()); + result = prime * result + ((label == null) ? 0 : label.hashCode()); + result = prime * result + ((to == null) ? 0 : to.hashCode()); + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + JsonEdgeSchema other = (JsonEdgeSchema) obj; + if (annotations == null) { + if (other.annotations != null) + return false; + } else if (!annotations.equals(other.annotations)) + return false; + if (from == null) { + if (other.from != null) + return false; + } else if (!from.equals(other.from)) + return false; + if (label == null) { + if (other.label != null) + return false; + } else if (!label.equals(other.label)) + return false; + if (to == null) { + if (other.to != null) + return false; + } else if (!to.equals(other.to)) + return false; + return true; + } + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonPropertySchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonPropertySchema.java new file mode 100644 index 00000000..b6934eb8 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonPropertySchema.java @@ -0,0 +1,192 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json.definitions; + +import java.util.Map; + +import org.onap.aai.schemaif.SchemaProviderException; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.SerializedName; + +public class JsonPropertySchema { + private static final Gson gson = new GsonBuilder().create(); + + private String name; + private Boolean required; + private Boolean unique; + + @SerializedName("type") + private String dataType; + + private String description; + + @SerializedName("default") + private String defaultValue; + + private Map annotations; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getRequired() { + return required; + } + + public void setRequired(Boolean required) { + this.required = required; + } + + public Boolean getUnique() { + return unique; + } + + public void setUnique(Boolean unique) { + this.unique = unique; + } + + public String getDataType() { + return dataType; + } + + public void setDataType(String dataType) { + this.dataType = dataType; + } + + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Map getAnnotations() { + return annotations; + } + + public void setAnnotations(Map annotations) { + this.annotations = annotations; + } + + public void validate() throws SchemaProviderException { + if ( (getName() == null) || (getName().isEmpty()) ) { + throw new SchemaProviderException(getName() + " property has no name"); + } + + if ( (getDataType() == null) || (getDataType().isEmpty()) ) { + throw new SchemaProviderException(getName() + " property has no type"); + } + } + + + public String toJson() { + return gson.toJson(this); + } + + public static JsonVertexSchema fromJson(String json) { + return gson.fromJson(json, JsonVertexSchema.class); + } + + @Override + public String toString() { + return "JsonPropertySchema [name=" + name + ", required=" + required + ", unique=" + unique + + ", dataType=" + dataType + ", description=" + description + ", defaultValue=" + + defaultValue + ", annotations=" + annotations + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((annotations == null) ? 0 : annotations.hashCode()); + result = prime * result + ((dataType == null) ? 0 : dataType.hashCode()); + result = prime * result + ((defaultValue == null) ? 0 : defaultValue.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((required == null) ? 0 : required.hashCode()); + result = prime * result + ((unique == null) ? 0 : unique.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + JsonPropertySchema other = (JsonPropertySchema) obj; + if (annotations == null) { + if (other.annotations != null) + return false; + } else if (!annotations.equals(other.annotations)) + return false; + if (dataType == null) { + if (other.dataType != null) + return false; + } else if (!dataType.equals(other.dataType)) + return false; + if (defaultValue == null) { + if (other.defaultValue != null) + return false; + } else if (!defaultValue.equals(other.defaultValue)) + return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (required == null) { + if (other.required != null) + return false; + } else if (!required.equals(other.required)) + return false; + if (unique == null) { + if (other.unique != null) + return false; + } else if (!unique.equals(other.unique)) + return false; + return true; + } + + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonSchema.java new file mode 100644 index 00000000..b9cacb87 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonSchema.java @@ -0,0 +1,167 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json.definitions; + +import java.util.List; + +import org.onap.aai.schemaif.SchemaProviderException; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.SerializedName; + +public class JsonSchema { + private static final Gson gson = new GsonBuilder().create(); + + @SerializedName("relationship_types") + private List relationshipTypes; + + @SerializedName("node_types") + private List nodeTypes; + + @SerializedName("data_types") + private List dataTypes; + + @SerializedName("common_node_properties") + private List commonNodeProps; + + + public void setRelationshipTypes(List relationshipTypes) { + this.relationshipTypes = relationshipTypes; + } + + public void setNodeTypes(List nodeTypes) { + this.nodeTypes = nodeTypes; + } + + public void setDataTypes(List dataTypes) { + this.dataTypes = dataTypes; + } + + public List getRelationshipTypes() { + return relationshipTypes; + } + + public List getNodeTypes() { + return nodeTypes; + } + + public List getDataTypes() { + return dataTypes; + } + + public List getCommonProperties() { + return commonNodeProps; + } + + public void setCommonProperties(List properties) { + this.commonNodeProps = properties; + } + + public void validate() throws SchemaProviderException { + if (getNodeTypes() != null) { + for (JsonVertexSchema vertexSchema : getNodeTypes()) { + vertexSchema.validate(); + } + } + + // Validate edges + if (getRelationshipTypes() != null) { + for (JsonEdgeSchema edgeSchema : getRelationshipTypes()) { + edgeSchema.validate(); + } + } + + // Validate data types + if (getDataTypes() != null) { + for (DataTypeDefinition typeSchema : getDataTypes()) { + typeSchema.validate(); + } + } + } + + public String toJson() { + return gson.toJson(this); + } + + public static JsonSchema fromJson(String json) throws SchemaProviderException { + try { + if (json == null || json.isEmpty()) { + throw new SchemaProviderException("Empty schema definition"); + } + + return gson.fromJson(json, JsonSchema.class); + } catch (Exception ex) { + throw new SchemaProviderException("Invalid json: " + ex.getMessage()); + } + } + + @Override + public String toString() { + return "JsonSchema [relationshipTypes=" + relationshipTypes + ", nodeTypes=" + nodeTypes + + ", dataTypes=" + dataTypes + ", commonNodeProps=" + commonNodeProps + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((commonNodeProps == null) ? 0 : commonNodeProps.hashCode()); + result = prime * result + ((dataTypes == null) ? 0 : dataTypes.hashCode()); + result = prime * result + ((nodeTypes == null) ? 0 : nodeTypes.hashCode()); + result = prime * result + ((relationshipTypes == null) ? 0 : relationshipTypes.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + JsonSchema other = (JsonSchema) obj; + if (commonNodeProps == null) { + if (other.commonNodeProps != null) + return false; + } else if (!commonNodeProps.equals(other.commonNodeProps)) + return false; + if (dataTypes == null) { + if (other.dataTypes != null) + return false; + } else if (!dataTypes.equals(other.dataTypes)) + return false; + if (nodeTypes == null) { + if (other.nodeTypes != null) + return false; + } else if (!nodeTypes.equals(other.nodeTypes)) + return false; + if (relationshipTypes == null) { + if (other.relationshipTypes != null) + return false; + } else if (!relationshipTypes.equals(other.relationshipTypes)) + return false; + return true; + } + + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonVertexSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonVertexSchema.java new file mode 100644 index 00000000..87a1eac7 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonVertexSchema.java @@ -0,0 +1,141 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json.definitions; + +import java.util.List; +import java.util.Map; + +import org.onap.aai.schemaif.SchemaProviderException; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class JsonVertexSchema { + private static final Gson gson = new GsonBuilder().create(); + + private String name; + private String description; + private List properties; + private Map annotations; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public Map getAnnotations() { + return annotations; + } + + public void setAnnotations(Map annotations) { + this.annotations = annotations; + } + + public void validate() throws SchemaProviderException { + if ( (getName() == null) || (getName().isEmpty()) ) { + throw new SchemaProviderException("Node definition missing a name"); + } + + if (getProperties() != null) { + for (JsonPropertySchema propSchema : getProperties()) { + propSchema.validate(); + } + } + } + + public String toJson() { + return gson.toJson(this); + } + + public static JsonVertexSchema fromJson(String json) { + return gson.fromJson(json, JsonVertexSchema.class); + } + + @Override + public String toString() { + return "JsonVertexSchema [name=" + name + ", description=" + description + ", properties=" + + properties + ", annotations=" + annotations + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((annotations == null) ? 0 : annotations.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((properties == null) ? 0 : properties.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + JsonVertexSchema other = (JsonVertexSchema) obj; + if (annotations == null) { + if (other.annotations != null) + return false; + } else if (!annotations.equals(other.annotations)) + return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (properties == null) { + if (other.properties != null) + return false; + } else if (!properties.equals(other.properties)) + return false; + return true; + } + + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/EdgePropsConfiguration.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/EdgePropsConfiguration.java new file mode 100644 index 00000000..bd30e77e --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/EdgePropsConfiguration.java @@ -0,0 +1,42 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.oxm; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +@Component +@PropertySource(value = "file:${edgeprops.ingest.file}", ignoreResourceNotFound = true) +public class EdgePropsConfiguration { + + @Value("${edgePropsDir}") + private String edgePropsDir; + + public String getEdgePropsDir() { + return edgePropsDir; + } + + public void setEdgePropsDir(String edgePropsDir) { + this.edgePropsDir = edgePropsDir; + } + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmEdgeSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmEdgeSchema.java new file mode 100644 index 00000000..336b6d9e --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmEdgeSchema.java @@ -0,0 +1,75 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.oxm; + +import java.util.HashMap; + +import org.onap.aai.edges.EdgeRule; +import org.onap.aai.edges.enums.EdgeProperty; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.EdgeSchema; +import org.onap.aai.schemaif.definitions.PropertySchema; +import org.onap.aai.schemaif.definitions.types.DataType; + + +public class FromOxmEdgeSchema extends EdgeSchema { + + public void fromEdgeRule(EdgeRule edgeRule) throws SchemaProviderException { + name = edgeRule.getLabel(); + source = edgeRule.getFrom(); + target = edgeRule.getTo(); + + switch (edgeRule.getMultiplicityRule()) { + case MANY2MANY: + multiplicity = Multiplicity.MANY_2_MANY; + break; + case MANY2ONE: + multiplicity = Multiplicity.MANY_2_ONE; + break; + case ONE2MANY: + multiplicity = Multiplicity.ONE_2_MANY; + break; + case ONE2ONE: + multiplicity = Multiplicity.ONE_2_ONE; + break; + } + + annotations = new HashMap(); + properties = new HashMap(); + + // TODO: For now these are hard-coded ... should read them from a config file or something + annotations.put(EdgeProperty.CONTAINS.toString().toLowerCase(), edgeRule.getContains()); + annotations.put(EdgeProperty.DELETE_OTHER_V.toString().toLowerCase(), edgeRule.getDeleteOtherV()); + annotations.put(EdgeProperty.PREVENT_DELETE.toString().toLowerCase(), edgeRule.getPreventDelete()); + + FromOxmPropertySchema pSchema = new FromOxmPropertySchema(); + pSchema.fromRelationship(EdgeProperty.CONTAINS.toString(), DataType.Type.STRING); + properties.put(EdgeProperty.CONTAINS.toString().toLowerCase(), pSchema); + + pSchema = new FromOxmPropertySchema(); + pSchema.fromRelationship(EdgeProperty.DELETE_OTHER_V.toString(), DataType.Type.STRING); + properties.put(EdgeProperty.DELETE_OTHER_V.toString().toLowerCase(), pSchema); + + pSchema = new FromOxmPropertySchema(); + pSchema.fromRelationship(EdgeProperty.PREVENT_DELETE.toString(), DataType.Type.STRING); + properties.put(EdgeProperty.PREVENT_DELETE.toString().toLowerCase(), pSchema); + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmPropertySchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmPropertySchema.java new file mode 100644 index 00000000..2174bce2 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmPropertySchema.java @@ -0,0 +1,141 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.oxm; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.persistence.dynamic.DynamicType; +import org.eclipse.persistence.internal.helper.DatabaseField; +import org.eclipse.persistence.mappings.DatabaseMapping; +import org.eclipse.persistence.oxm.XMLField; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.PropertySchema; +import org.onap.aai.schemaif.definitions.types.BooleanDataType; +import org.onap.aai.schemaif.definitions.types.DataType; +import org.onap.aai.schemaif.definitions.types.FloatDataType; +import org.onap.aai.schemaif.definitions.types.IntDataType; +import org.onap.aai.schemaif.definitions.types.LongDataType; +import org.onap.aai.schemaif.definitions.types.StringDataType; + + +public class FromOxmPropertySchema extends PropertySchema { + + // Handle vertex properties from OXM + public void fromOxm(DatabaseMapping mapping, DynamicType dynType, boolean reserved) throws SchemaProviderException { + DatabaseField field = mapping.getField(); + if (field.getName().contains("/")) { + name = field.getName().substring(0, field.getName().indexOf("/")); + } else { + name = field.getName(); + } + + defaultValue = mapping.getProperties().get("defaultValue") == null ? "" + : mapping.getProperties().get("defaultValue").toString(); + + if (isPrimaryKeyOxm(name, dynType)) { + unique = true; + required = true; + } + else { + required = ((XMLField) field).isRequired(); + unique = false; + } + + isReserved = reserved; + + String oxmType = ((XMLField) field).getTypeName() != null ? ((XMLField) field).getTypeName() : ""; + if (!mapping.isAbstractDirectMapping()) { + // treat complex types as string blobs in oxm + dataType = new StringDataType(); + } else { + if (oxmType.equalsIgnoreCase("java.lang.String")) { + dataType = new StringDataType(); + } else if (oxmType.equalsIgnoreCase("java.lang.Long")) { + dataType = new LongDataType(); + } else if (oxmType.equalsIgnoreCase("java.lang.Boolean")) { + dataType = new BooleanDataType(); + } else if (oxmType.equalsIgnoreCase("java.lang.Integer")) { + dataType = new IntDataType(); + } else if (oxmType.equalsIgnoreCase("java.lang.Float")) { + dataType = new FloatDataType(); + } else { + throw new SchemaProviderException("Invalid OXM property type: " + oxmType); + } + } + + // Check annotations + annotations = new HashMap(); + Map oxmProps = mapping.getProperties(); + for (Map.Entry entry : oxmProps.entrySet()) { + if (entry.getValue() instanceof String) { + annotations.put(entry.getKey().toLowerCase(), (String)entry.getValue()); + } + } + } + + // Handle edge properties from DBEdgeRules + public void fromRelationship(String propName, DataType.Type propDataType) throws SchemaProviderException { + name = propName; + required = false; + defaultValue = ""; + unique = false; + annotations = new HashMap(); + + switch (propDataType) { + case STRING: + dataType = new StringDataType(); + break; + case INT: + dataType = new IntDataType(); + break; + case FLOAT: + dataType = new FloatDataType(); + break; + case LONG: + dataType = new LongDataType(); + break; + case BOOL: + dataType = new BooleanDataType(); + break; + default: + throw new SchemaProviderException("Invalid EdgeRule property type: " + propDataType); + } + } + + private boolean isPrimaryKeyOxm(String propName, DynamicType dynType) { + List primaryKeyList = dynType.getDescriptor().getPrimaryKeyFieldNames(); + if ( (primaryKeyList == null) || (primaryKeyList.size() == 0) ) { + return false; + } + + for (String key : primaryKeyList) { + String keyName = key.substring(0, key.indexOf('/')); + if (keyName.equals(propName)) { + return true; + } + } + + return false; + } + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmVertexSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmVertexSchema.java new file mode 100644 index 00000000..6083429b --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmVertexSchema.java @@ -0,0 +1,95 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.oxm; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.persistence.dynamic.DynamicType; +import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; +import org.eclipse.persistence.mappings.DatabaseMapping; +import org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping; +import org.eclipse.persistence.oxm.mappings.XMLAnyObjectMapping; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.PropertySchema; +import org.onap.aai.schemaif.definitions.VertexSchema; + +import com.google.common.base.CaseFormat; + +public class FromOxmVertexSchema extends VertexSchema { + public void fromOxm(String vertexType, DynamicJAXBContext jaxbContext, HashMap xmlElementLookup) throws SchemaProviderException { + name = vertexType; + properties = new HashMap(); + annotations = new HashMap(); + + String javaTypeName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, vertexType); + DynamicType modelObjectType = jaxbContext.getDynamicType(javaTypeName); + + if (modelObjectType == null) { + // Try to lookup by xml root element by exact match + modelObjectType = xmlElementLookup.get(vertexType); + } + + if (modelObjectType == null) { + // Try to lookup by xml root element by lowercase + modelObjectType = xmlElementLookup.get(vertexType.toLowerCase()); + } + + if (modelObjectType == null) { + // Direct lookup as java-type name + modelObjectType = jaxbContext.getDynamicType(vertexType); + } + + if (modelObjectType == null) { + // Vertex isn't found in the OXM + throw new SchemaProviderException("Vertex " + vertexType + " not found in OXM"); + } + + // Check annotations + Map oxmProps = modelObjectType.getDescriptor().getProperties(); + for (Map.Entry entry : oxmProps.entrySet()) { + if (entry.getValue() instanceof String) { + annotations.put(entry.getKey().toLowerCase(), (String)entry.getValue()); + } + } + + // Regular props + for (DatabaseMapping mapping : modelObjectType.getDescriptor().getMappings()) { + if (mapping instanceof XMLAnyObjectMapping) + continue; + if(mapping instanceof XMLAnyCollectionMapping) + continue; + FromOxmPropertySchema propSchema = new FromOxmPropertySchema(); + propSchema.fromOxm(mapping, modelObjectType, false); + properties.put(propSchema.getName().toLowerCase(), propSchema); + } + + // Reserved Props + final DynamicType reservedType = jaxbContext.getDynamicType("ReservedPropNames"); + for (DatabaseMapping mapping : reservedType.getDescriptor().getMappings()) { + if (mapping.isAbstractDirectMapping()) { + FromOxmPropertySchema propSchema = new FromOxmPropertySchema(); + propSchema.fromOxm(mapping, reservedType, true); + properties.put(propSchema.getName().toLowerCase(), propSchema); + } + } + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmEdgeRulesLoader.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmEdgeRulesLoader.java new file mode 100644 index 00000000..39e7039f --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmEdgeRulesLoader.java @@ -0,0 +1,246 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.oxm; + +import com.google.common.collect.Multimap; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.apache.commons.io.IOUtils; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.edges.EdgeIngestor; +import org.onap.aai.edges.EdgeRule; +import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.SchemaProviderMsgs; +import org.onap.aai.setup.SchemaVersion; +import org.onap.aai.setup.Translator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class OxmEdgeRulesLoader { + + private static Translator translator; + private static EdgeIngestor edgeIngestor; + + private static EdgePropsConfiguration edgePropsConfiguration; + + private static Map versionContextMap = new ConcurrentHashMap<>(); + + static final Pattern versionPattern = Pattern.compile("(?i)v(\\d*)"); + static final String propsPrefix = "edge_properties_"; + static final String propsSuffix = ".json"; + final static Pattern propsFilePattern = Pattern.compile(propsPrefix + "(.*)" + propsSuffix); + final static Pattern propsVersionPattern = Pattern.compile("(?i)v\\d*"); + + private static org.onap.aai.cl.api.Logger logger = + LoggerFactory.getInstance().getLogger(OxmEdgeRulesLoader.class.getName()); + + private OxmEdgeRulesLoader() {} + + /** + * This constructor presents an awkward marrying of Spring bean creation and static method use. This + * is technical debt that will need fixing. + * + * @param translator contains schema versions configuration + * @param edgeIngestor provides edge rules + * @param edgePropsConfiguration edge property validation configuration + */ + @Autowired + public OxmEdgeRulesLoader(Translator translator, EdgeIngestor edgeIngestor, + EdgePropsConfiguration edgePropsConfiguration) { + OxmEdgeRulesLoader.translator = translator; + OxmEdgeRulesLoader.edgeIngestor = edgeIngestor; + OxmEdgeRulesLoader.edgePropsConfiguration = edgePropsConfiguration; + } + + /** + * Finds all DB Edge Rules and Edge Properties files for all OXM models. + * + * @throws SchemaProviderException + * @throws SchemaProviderException + */ + public static synchronized void loadModels() throws SchemaProviderException { + Map propFiles = edgePropertyFiles(edgePropsConfiguration); + + if (logger.isDebugEnabled()) { + logger.debug("Loading DB Edge Rules"); + } + + for (String version : OxmSchemaLoader.getLoadedOXMVersions()) { + try { + SchemaVersion schemaVersion = translator.getSchemaVersions().getVersions().stream() + .filter(s -> s.toString().equalsIgnoreCase(version)).findAny().orElse(null); + loadModel(schemaVersion, edgeIngestor, propFiles); + } catch (IOException | EdgeRuleNotFoundException e) { + throw new SchemaProviderException(e.getMessage(), e); + } + } + } + + /** + * Loads DB Edge Rules and Edge Properties for a given version. + * + * @throws SchemaProviderException + */ + + public static synchronized void loadModels(String v) throws SchemaProviderException { + Map propFiles = edgePropertyFiles(edgePropsConfiguration); + + if (logger.isDebugEnabled()) { + logger.debug("Loading DB Edge Rules "); + } + + try { + SchemaVersion schemaVersion = translator.getSchemaVersions().getVersions().stream() + .filter(s -> s.toString().equalsIgnoreCase(v)).findAny().orElse(null); + + loadModel(schemaVersion, edgeIngestor, propFiles); + } catch (IOException | EdgeRuleNotFoundException e) { + throw new SchemaProviderException(e.getMessage()); + } + } + + /** + * Retrieves the DB Edge Rule relationship schema for a given version. + * + * @param version - The OXM version that we want the DB Edge Rule for. + * @return - A RelationshipSchema of the DB Edge Rule for the OXM version. + * @throws SchemaProviderException + */ + public static RelationshipSchema getSchemaForVersion(String version) throws SchemaProviderException { + + // If we haven't already loaded in the available OXM models, then do so now. + if (versionContextMap == null || versionContextMap.isEmpty()) { + loadModels(); + } else if (!versionContextMap.containsKey(version)) { + logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "Error loading DB Edge Rules for: " + version); + throw new SchemaProviderException("Error loading DB Edge Rules for: " + version); + } + + return versionContextMap.get(version); + } + + /** + * Retrieves the DB Edge Rule relationship schema for all loaded OXM versions. + * + * @return - A Map of the OXM version and it's corresponding RelationshipSchema of the DB Edge Rule. + * @throws SchemaProviderException + */ + public static Map getSchemas() throws SchemaProviderException { + + // If we haven't already loaded in the available OXM models, then do so now. + if (versionContextMap == null || versionContextMap.isEmpty()) { + loadModels(); + } + return versionContextMap; + } + + /** + * Returns the latest available DB Edge Rule version. + * + * @return - A Map of the OXM version and it's corresponding RelationshipSchema of the DB Edge Rule. + * @throws SchemaProviderException + */ + public static String getLatestSchemaVersion() throws SchemaProviderException { + + // If we haven't already loaded in the available OXM models, then do so now. + if (versionContextMap == null || versionContextMap.isEmpty()) { + loadModels(); + } + + // If there are still no models available, then there's not much we can do... + if (versionContextMap.isEmpty()) { + logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "No available DB Edge Rules to get latest version for."); + throw new SchemaProviderException("No available DB Edge Rules to get latest version for."); + } + + // Iterate over the available model versions to determine which is the most + // recent. + Integer latestVersion = null; + String latestVersionStr = null; + for (String versionKey : versionContextMap.keySet()) { + + Matcher matcher = versionPattern.matcher(versionKey); + if (matcher.find()) { + + int currentVersion = Integer.parseInt(matcher.group(1)); + + if ((latestVersion == null) || (currentVersion > latestVersion)) { + latestVersion = currentVersion; + latestVersionStr = versionKey; + } + } + } + + return latestVersionStr; + } + + /** + * Reset the loaded DB Edge Rule schemas + * + */ + public static void resetSchemaVersionContext() { + versionContextMap = new ConcurrentHashMap<>(); + } + + private static synchronized void loadModel(SchemaVersion version, EdgeIngestor edgeIngestor, + Map props) throws IOException, SchemaProviderException, EdgeRuleNotFoundException { + + Multimap edges = edgeIngestor.getAllRules(version); + String edgeProps; + if (props.get(version.toString().toLowerCase()) != null) { + edgeProps = IOUtils.toString(new FileInputStream(props.get(version.toString().toLowerCase())), "UTF-8"); + } else { + throw new FileNotFoundException("The Edge Properties file for OXM version " + version + "was not found."); + } + if (edges != null) { + RelationshipSchema rs = new RelationshipSchema(edges, edgeProps); + versionContextMap.put(version.toString().toLowerCase(), rs); + logger.info(SchemaProviderMsgs.LOADED_DB_RULE_FILE, version.toString()); + } + } + + private static Map edgePropertyFiles(EdgePropsConfiguration edgePropsConfiguration) + throws SchemaProviderException { + Map propsFiles = Arrays + .stream(new File(edgePropsConfiguration.getEdgePropsDir()) + .listFiles((d, name) -> propsFilePattern.matcher(name).matches())) + .collect(Collectors.toMap(new Function() { + @Override + public String apply(File f) { + Matcher m1 = propsVersionPattern.matcher(f.getName()); + m1.find(); + return m1.group(0); + } + }, f -> f)); + return propsFiles; + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaLoader.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaLoader.java new file mode 100644 index 00000000..b3708b12 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaLoader.java @@ -0,0 +1,236 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.oxm; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.persistence.dynamic.DynamicType; +import org.eclipse.persistence.internal.oxm.mappings.Descriptor; +import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.nodes.NodeIngestor; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.SchemaProviderMsgs; +import org.onap.aai.schemaif.definitions.VertexSchema; +import org.onap.aai.setup.SchemaVersion; +import org.onap.aai.setup.Translator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * This class contains all of the logic for importing OXM model schemas from the available OXM + * schema files. + */ +@Component +public class OxmSchemaLoader { + + private static Translator translator; + private static NodeIngestor nodeIngestor; + + private static Map versionContextMap = new ConcurrentHashMap<>(); + private static Map> xmlElementLookup = new ConcurrentHashMap<>(); + private static Map> vertexLookup = new ConcurrentHashMap<>(); + + final static Pattern versionPattern = Pattern.compile("(?i)v(\\d*)"); + + private static org.onap.aai.cl.api.Logger logger = + LoggerFactory.getInstance().getLogger(OxmSchemaLoader.class.getName()); + + private OxmSchemaLoader() {} + + /** + * This constructor presents an awkward marrying of Spring bean creation and static method use. This + * is technical debt that will need fixing. + * + * @param translator contains schema versions configuration + * @param nodeIngestor provides DynamicJAXBContext for the OXM version + */ + @Autowired + public OxmSchemaLoader(Translator translator, NodeIngestor nodeIngestor) { + OxmSchemaLoader.translator = translator; + OxmSchemaLoader.nodeIngestor = nodeIngestor; + } + + /** + * Finds all OXM model files + * + * @throws SchemaProviderException + * @throws IOException + * + */ + public synchronized static void loadModels() throws SchemaProviderException { + if (logger.isDebugEnabled()) { + logger.debug("Loading OXM Models"); + } + + for (SchemaVersion oxmVersion : translator.getSchemaVersions().getVersions()) { + DynamicJAXBContext jaxbContext = nodeIngestor.getContextForVersion(oxmVersion); + if (jaxbContext != null) { + loadModel(oxmVersion.toString(), jaxbContext); + } + } + } + + private synchronized static void loadModel(String oxmVersion, DynamicJAXBContext jaxbContext) { + versionContextMap.put(oxmVersion, jaxbContext); + loadXmlLookupMap(oxmVersion, jaxbContext); + loadVertexLookupMap(oxmVersion, jaxbContext); + logger.info(SchemaProviderMsgs.LOADED_SCHEMA_FILE, oxmVersion); + } + + /** + * Retrieves the JAXB context for the specified OXM model version. + * + * @param version - The OXM version that we want the JAXB context for. + * + * @return - A JAXB context derived from the OXM model schema. + * + * @throws SchemaProviderException + */ + public static DynamicJAXBContext getContextForVersion(String version) throws SchemaProviderException { + + // If we haven't already loaded in the available OXM models, then do so now. + if (versionContextMap == null || versionContextMap.isEmpty()) { + loadModels(); + } else if (!versionContextMap.containsKey(version)) { + throw new SchemaProviderException("Error loading oxm model: " + version); + } + + return versionContextMap.get(version); + } + + public static String getLatestVersion() throws SchemaProviderException { + + // If we haven't already loaded in the available OXM models, then do so now. + if (versionContextMap == null || versionContextMap.isEmpty()) { + loadModels(); + } + + // If there are still no models available, then there's not much we can do... + if (versionContextMap.isEmpty()) { + throw new SchemaProviderException("No available OXM schemas to get latest version for."); + } + + // Iterate over the available model versions to determine which is the most + // recent. + Integer latestVersion = null; + String latestVersionStr = null; + for (String versionKey : versionContextMap.keySet()) { + + Matcher matcher = versionPattern.matcher(versionKey); + if (matcher.find()) { + + int currentVersion = Integer.valueOf(matcher.group(1)); + + if ((latestVersion == null) || (currentVersion > latestVersion)) { + latestVersion = currentVersion; + latestVersionStr = versionKey; + } + } + } + + return latestVersionStr; + } + + private static void loadXmlLookupMap(String version, DynamicJAXBContext jaxbContext) { + + @SuppressWarnings("rawtypes") + List descriptorsList = jaxbContext.getXMLContext().getDescriptors(); + HashMap types = new HashMap(); + + for (@SuppressWarnings("rawtypes") + Descriptor desc : descriptorsList) { + + DynamicType entity = jaxbContext.getDynamicType(desc.getAlias()); + String entityName = desc.getDefaultRootElement(); + types.put(entityName, entity); + } + xmlElementLookup.put(version, types); + } + + private static void loadVertexLookupMap(String version, DynamicJAXBContext jaxbContext) { + + @SuppressWarnings("rawtypes") + List descriptorsList = jaxbContext.getXMLContext().getDescriptors(); + HashMap vertexMap = new HashMap(); + + for (@SuppressWarnings("rawtypes") + Descriptor desc : descriptorsList) { + try { + FromOxmVertexSchema vs = new FromOxmVertexSchema(); + vs.fromOxm(desc.getDefaultRootElement(), jaxbContext, getXmlLookupMap(version)); + vertexMap.put(vs.getName(), vs); + } catch (SchemaProviderException e) { + continue; + } + } + vertexLookup.put(version, vertexMap); + } + + /** + * Retrieves the list of all Loaded OXM versions. + * + * @return - A List of Strings of all loaded OXM versions. + * + * @throws SpikeException + */ + public static List getLoadedOXMVersions() throws SchemaProviderException { + // If we haven't already loaded in the available OXM models, then do so now. + if (versionContextMap == null || versionContextMap.isEmpty()) { + loadModels(); + } + // If there are still no models available, then there's not much we can do... + if (versionContextMap.isEmpty()) { + logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "No available OXM schemas to get versions for."); + throw new SchemaProviderException("No available OXM schemas to get latest version for."); + } + List versions = new ArrayList(); + for (String versionKey : versionContextMap.keySet()) { + Matcher matcher = versionPattern.matcher(versionKey); + if (matcher.find()) { + versions.add("V" + matcher.group(1)); + } + } + return versions; + } + + public static HashMap getXmlLookupMap(String version) { + return xmlElementLookup.get(version); + } + + public static HashMap getVertexLookupForVersion(String version) throws SchemaProviderException { + // If we haven't already loaded in the available OXM models, then do so now. + if (vertexLookup == null || vertexLookup.isEmpty()) { + loadModels(); + } else if (!vertexLookup.containsKey(version)) { + throw new SchemaProviderException("Error loading oxm model: " + version); + } + return vertexLookup.get(version); + } + +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaProvider.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaProvider.java new file mode 100644 index 00000000..0ad8bf45 --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaProvider.java @@ -0,0 +1,117 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.oxm; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; +import org.onap.aai.edges.EdgeRule; +import org.onap.aai.schemaif.SchemaProvider; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.EdgeSchema; +import org.onap.aai.schemaif.definitions.VertexSchema; + + +public class OxmSchemaProvider implements SchemaProvider { + + @Override + public void loadSchema() throws SchemaProviderException { + OxmEdgeRulesLoader.loadModels(); + OxmSchemaLoader.loadModels(); + } + + @Override + public String getLatestSchemaVersion() throws SchemaProviderException { + return OxmSchemaLoader.getLatestVersion(); + } + + @Override + public VertexSchema getVertexSchema(String vertexName, String schemaVersion) throws SchemaProviderException { + DynamicJAXBContext jaxbContext = OxmSchemaLoader.getContextForVersion(schemaVersion); + FromOxmVertexSchema vs = new FromOxmVertexSchema(); + + try { + vs.fromOxm(vertexName, jaxbContext, OxmSchemaLoader.getXmlLookupMap(schemaVersion)); + } + catch (SchemaProviderException ex) { + // Node doesn't exist in schema. Return null. + return null; + } + + return vs; + } + + @Override + public EdgeSchema getEdgeSchema(String edgeType, String sourceVertex, String targetVertex, String version) + throws SchemaProviderException { + RelationshipSchema relSchema = OxmEdgeRulesLoader.getSchemaForVersion(version); + String key = sourceVertex + ":" + targetVertex + ":" + edgeType; + + EdgeRule edgeRule = relSchema.lookupEdgeRule(key); + if (edgeRule == null) { + return null; + } + + FromOxmEdgeSchema es = new FromOxmEdgeSchema(); + es.fromEdgeRule(edgeRule); + + return es; + } + + @Override + public Set getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException { + RelationshipSchema relSchema = OxmEdgeRulesLoader.getSchemaForVersion(version); + Set edges = new HashSet(); + List rules = relSchema.lookupAdjacentEdges(vertexType); + + for (EdgeRule rule : rules) { + FromOxmEdgeSchema es = new FromOxmEdgeSchema(); + es.fromEdgeRule(rule); + edges.add(es); + } + + return edges; + } + + @Override + public Set getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version) throws SchemaProviderException { + RelationshipSchema relSchema = OxmEdgeRulesLoader.getSchemaForVersion(version); + Set edges = new HashSet(); + Set relTypes = relSchema.getValidRelationTypes(sourceType, targetType); + + for (String type : relTypes) { + EdgeSchema edgeSchema = getEdgeSchema(type, sourceType, targetType, version); + if (edgeSchema != null) { + edges.add(edgeSchema); + } + } + + return edges; + } + + @Override + public Map getVertexMap(String schemaVersion) throws SchemaProviderException { + return OxmSchemaLoader.getVertexLookupForVersion(schemaVersion); + } +} diff --git a/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/RelationshipSchema.java b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/RelationshipSchema.java new file mode 100644 index 00000000..fa4fe45d --- /dev/null +++ b/aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/RelationshipSchema.java @@ -0,0 +1,189 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.schemaif.oxm; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.codehaus.jackson.map.ObjectMapper; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.edges.EdgeRule; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.SchemaProviderMsgs; + +import com.google.common.collect.Multimap; + + +public class RelationshipSchema { + + + public static final String SCHEMA_SOURCE_NODE_TYPE = "from"; + public static final String SCHEMA_TARGET_NODE_TYPE = "to"; + public static final String SCHEMA_RELATIONSHIP_TYPE = "label"; + public static final String SCHEMA_RULES_ARRAY = "rules"; + + private static org.onap.aai.cl.api.Logger logger = + LoggerFactory.getInstance().getLogger(RelationshipSchema.class.getName()); + + private Map>> relations = new HashMap<>(); + /** + * Hashmap of valid relationship types along with properties. + */ + private Map>> relationTypes = new HashMap<>(); + private Map relationshipRules = new HashMap<>(); + + // A map storing the list of valid edge types for a source/target pair + private Map> edgeTypesForNodePair = new HashMap<>(); + + + public RelationshipSchema(Multimap rules, String props) throws SchemaProviderException, IOException { + HashMap properties = new ObjectMapper().readValue(props, HashMap.class); + + // hold the true values of the edge rules by key + for (EdgeRule rule : rules.values()) { + String nodePairKey = buildNodePairKey(rule.getFrom(), rule.getTo()); + if (edgeTypesForNodePair.get(nodePairKey) == null) { + Set typeSet = new HashSet(); + typeSet.add(rule.getLabel()); + edgeTypesForNodePair.put(nodePairKey, typeSet); + } + else { + edgeTypesForNodePair.get(nodePairKey).add(rule.getLabel()); + } + + String key = buildRelation(rule.getFrom(), rule.getTo(), rule.getLabel()); + relationshipRules.put(key, rule); + } + + Map> edgeProps = + properties.entrySet().stream().collect(Collectors.toMap(p -> p.getKey(), p -> { + try { + return resolveClass(p.getValue()); + } catch (SchemaProviderException | ClassNotFoundException e) { + logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "Error in RelationshipSchema: " + e); + } + return null; + })); + + rules.entries().forEach((kv) -> { + relationTypes.put(kv.getValue().getLabel(), edgeProps); + relations.put(buildRelation(kv.getValue().getFrom(), kv.getValue().getTo(), kv.getValue().getLabel()), + edgeProps); + }); + } + + public EdgeRule lookupEdgeRule(String key) throws SchemaProviderException { + return relationshipRules.get(key); + } + + public List lookupAdjacentEdges(String vertex) throws SchemaProviderException { + List edges = new ArrayList(); + for (EdgeRule rule : relationshipRules.values()) { + if (rule.getFrom().equals(vertex) || rule.getTo().equals(vertex)) { + edges.add(rule); + } + } + + return edges; + } + + public RelationshipSchema(List jsonStrings) throws SchemaProviderException, IOException { + String edgeRules = jsonStrings.get(0); + String props = jsonStrings.get(1); + + HashMap>> rules = + new ObjectMapper().readValue(edgeRules, HashMap.class); + HashMap properties = new ObjectMapper().readValue(props, HashMap.class); + Map> edgeProps = + properties.entrySet().stream().collect(Collectors.toMap(p -> p.getKey(), p -> { + try { + return resolveClass(p.getValue()); + } catch (SchemaProviderException | ClassNotFoundException e) { + logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "Error in RelationshipSchema: " + e); + } + return null; + })); + + rules.get(SCHEMA_RULES_ARRAY).forEach(l -> { + relationTypes.put(l.get(SCHEMA_RELATIONSHIP_TYPE), edgeProps); + relations.put(buildRelation(l.get(SCHEMA_SOURCE_NODE_TYPE), l.get(SCHEMA_TARGET_NODE_TYPE), + l.get(SCHEMA_RELATIONSHIP_TYPE)), edgeProps); + }); + } + + + + public Map> lookupRelation(String key) { + return this.relations.get(key); + } + + public Map> lookupRelationType(String type) { + return this.relationTypes.get(type); + } + + public boolean isValidType(String type) { + return relationTypes.containsKey(type); + } + + + private String buildRelation(String source, String target, String relation) { + return source + ":" + target + ":" + relation; + } + + public Set getValidRelationTypes(String source, String target) { + Set typeList = edgeTypesForNodePair.get(buildNodePairKey(source, target)); + + if (typeList == null) { + return new HashSet(); + } + + return typeList; + } + + private String buildNodePairKey(String source, String target) { + return source + ":" + target; + } + + + private Class resolveClass(String type) throws SchemaProviderException, ClassNotFoundException { + Class clazz = Class.forName(type); + validateClassTypes(clazz); + return clazz; + } + + private void validateClassTypes(Class clazz) throws SchemaProviderException { + if (!clazz.isAssignableFrom(Integer.class) && !clazz.isAssignableFrom(Double.class) + && !clazz.isAssignableFrom(Boolean.class) && !clazz.isAssignableFrom(String.class)) { + throw new SchemaProviderException("BAD_REQUEST"); + } + } +} + + diff --git a/aai-schema-abstraction/src/main/resources/logging/SchemaProviderMsgs.properties b/aai-schema-abstraction/src/main/resources/logging/SchemaProviderMsgs.properties new file mode 100644 index 00000000..0feb2acd --- /dev/null +++ b/aai-schema-abstraction/src/main/resources/logging/SchemaProviderMsgs.properties @@ -0,0 +1,16 @@ + +## Error Logs +SCHEMA_LOAD_ERROR=\ + PVD0500E|\ + Unable to load schema: {0} + +## Info Logs +LOADED_SCHEMA_FILE=\ + PVD0001I|\ + Successfully loaded schema: {0} + +LOADED_DB_RULE_FILE=\ + PVD0002I|\ + Successfully loaded DB Edge Rule and Edge Properties for: {0} + + diff --git a/aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/json/JsonSchemaProviderTest.java b/aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/json/JsonSchemaProviderTest.java new file mode 100644 index 00000000..83ba9e33 --- /dev/null +++ b/aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/json/JsonSchemaProviderTest.java @@ -0,0 +1,600 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.json; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.EdgeSchema; +import org.onap.aai.schemaif.definitions.PropertySchema; +import org.onap.aai.schemaif.definitions.VertexSchema; +import org.onap.aai.schemaif.definitions.types.ComplexDataType; +import org.onap.aai.schemaif.definitions.types.DataType.Type; +import org.onap.aai.schemaif.definitions.types.ListDataType; +import org.onap.aai.schemaif.definitions.types.MapDataType; +import org.onap.aai.schemaif.json.definitions.DataTypeDefinition; +import org.onap.aai.schemaif.json.definitions.JsonEdgeSchema; +import org.onap.aai.schemaif.json.definitions.JsonPropertySchema; +import org.onap.aai.schemaif.json.definitions.JsonSchema; +import org.onap.aai.schemaif.json.definitions.JsonVertexSchema; + + +public class JsonSchemaProviderTest { + + JsonSchemaProviderConfig config = new JsonSchemaProviderConfig(); + + @Before + public void init() throws Exception { + config.setSchemaServiceBaseUrl("https://testurl.com:8443"); + config.setSchemaServiceCertFile("/c/certfile"); + config.setSchemaServiceCertPwd("my-password"); + config.setServiceName("test-service"); + } + + @Test + public void testJsonSchemaLoad() { + try { + String testSchema = readFile("src/test/resources/json/jsonSchema.json"); + JsonSchema jsonSchema = JsonSchema.fromJson(testSchema); + + // Test Edge Schema + JsonEdgeSchema edgeSchema = null; + for (JsonEdgeSchema edge : jsonSchema.getRelationshipTypes()) { + if ( (edge.getFrom().equals("onap.nodes.sdwan.uCPE")) + && (edge.getTo().equals("onap.nodes.sdwan.service.SubscriberService")) ) { + edgeSchema = edge; + break; + } + } + + assertTrue(edgeSchema.getLabel().equals("onap.relationships.sdwan.BelongsTo")); + + // Test Node Schema + JsonVertexSchema vertexSchema = null; + for (JsonVertexSchema v : jsonSchema.getNodeTypes()) { + if ( (v.getName().equals("org.onap.resource.NetworkRules")) ) { + vertexSchema = v; + break; + } + } + + assertTrue(vertexSchema.getProperties().size() == 2); + + JsonPropertySchema propSchema = null; + for (JsonPropertySchema p : vertexSchema.getProperties()) { + if ( (p.getName().equals("network_policy_entries")) ) { + propSchema = p; + break; + } + } + + assertTrue(propSchema.getRequired() == false); + assertTrue(propSchema.getUnique() == false); + assertTrue(propSchema.getDataType().equals("org.onap.datatypes.RuleList")); + assertTrue(propSchema.getDefaultValue().equals("")); + assertTrue(propSchema.getAnnotations().size() == 4); + + // Test DataType Schema + DataTypeDefinition dataType = null; + for (DataTypeDefinition d : jsonSchema.getDataTypes()) { + if ( (d.getName().equals("org.onap.datatypes.network.VlanRequirements")) ) { + dataType = d; + break; + } + } + + assertTrue(dataType.getName().equals("org.onap.datatypes.network.VlanRequirements")); + assertTrue(dataType.getProperties().size() == 4); + + propSchema = null; + for (JsonPropertySchema p : dataType.getProperties()) { + if ( (p.getName().equals("vlan_type")) ) { + propSchema = p; + break; + } + } + + assertTrue(propSchema.getRequired() == false); + assertTrue(propSchema.getDataType().equals("string")); + assertTrue(propSchema.getDefaultValue().equals("")); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testJsonSchemaTranslateVertex() { + try { + String testSchema = readFile("src/test/resources/json/jsonSchema.json"); + JsonSchemaProvider schemaProvider = new JsonSchemaProvider(config); + schemaProvider.loadSchema(testSchema, schemaProvider.getLatestSchemaVersion()); + + VertexSchema vertSchema = + schemaProvider.getVertexSchema("tosca.nodes.objectstorage", + schemaProvider.getLatestSchemaVersion()); + System.out.println(vertSchema.toString()); + + // Validate vertex schema + assertTrue(vertSchema.getName().equals("tosca.nodes.ObjectStorage")); + assertTrue(vertSchema.getAnnotationValue("searchable").equals("size,name")); + assertTrue(vertSchema.getAnnotationValue("indexedProps").equals("aai-uuid,name")); + + PropertySchema propSchema = vertSchema.getPropertySchema("Name"); + assertTrue(propSchema.getName().equals("name")); + assertTrue(propSchema.getDefaultValue().equals("")); + assertTrue(propSchema.isRequired()); + assertTrue(!propSchema.isKey()); + assertTrue(!propSchema.isReserved()); + assertTrue(propSchema.getDataType().getType().compareTo(Type.STRING) == 0); + assertTrue(propSchema.getAnnotationValue("Source_of_truth_type").equals("AAI")); + + propSchema = vertSchema.getPropertySchema("Size"); + assertTrue(propSchema.getName().equals("size")); + assertTrue(propSchema.getDefaultValue().equals("50")); + assertTrue(propSchema.getDataType().getType().compareTo(Type.INT) == 0); + + propSchema = vertSchema.getPropertySchema("source-of-truth"); + assertTrue(propSchema.getName().equals("source-of-truth")); + assertTrue(!propSchema.isRequired()); + assertTrue(propSchema.isReserved()); + assertTrue(propSchema.getDataType().getType().compareTo(Type.STRING) == 0); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testJsonSchemaTranslateEdge() { + try { + String testSchema = readFile("src/test/resources/json/jsonSchema.json"); + JsonSchemaProvider schemaProvider = new JsonSchemaProvider(config); + schemaProvider.loadSchema(testSchema, schemaProvider.getLatestSchemaVersion()); + + EdgeSchema edgeSchema = schemaProvider.getEdgeSchema("tosca.relationships.hostedOn", + "tosca.nodes.Softwarecomponent", "tosca.nodes.compute", + schemaProvider.getLatestSchemaVersion()); + System.out.println(edgeSchema.toString()); + + // Validate edge schema + assertTrue(edgeSchema.getName().equals("tosca.relationships.HostedOn")); + assertTrue(edgeSchema.getSource().equals("tosca.nodes.SoftwareComponent")); + assertTrue(edgeSchema.getTarget().equals("tosca.nodes.Compute")); + assertTrue(edgeSchema.getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_MANY)); + assertTrue(edgeSchema.getAnnotationValue("contains-other-v").equals("NONE")); + + + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testJsonSchemaTranslateAdjacentEdge() { + try { + String testSchema = readFile("src/test/resources/json/jsonSchema.json"); + JsonSchemaProvider schemaProvider = new JsonSchemaProvider(config); + schemaProvider.loadSchema(testSchema, schemaProvider.getLatestSchemaVersion()); + + Set edgeSchemaList = + schemaProvider.getAdjacentEdgeSchema("tosca.nodes.Database", + schemaProvider.getLatestSchemaVersion()); + + // Validate edge schema + assertTrue(edgeSchemaList.size() == 3); + + for (EdgeSchema es : edgeSchemaList) { + System.out.println(es.toString()); + if (es.getName().equals("tosca.relationships.HostedOn")) { + assertTrue(es.getSource().equals("tosca.nodes.Database")); + assertTrue(es.getTarget().equals("tosca.nodes.DBMS")); + assertTrue(es.getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_MANY)); + } + else if (es.getName().equals("tosca.relationships.RoutesTo")) { + assertTrue(es.getSource().equals("tosca.nodes.LoadBalancer")); + assertTrue(es.getTarget().equals("tosca.nodes.Database")); + assertTrue(es.getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_MANY)); + } + else if (es.getName().equals("tosca.relationships.Uses")) { + assertTrue(es.getSource().equals("tosca.nodes.LoadBalancer")); + assertTrue(es.getTarget().equals("tosca.nodes.Database")); + assertTrue(es.getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_MANY)); + } + else { + assertTrue(false); + } + } + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testJsonSchemaSourceTargetEdges() { + try { + String testSchema = readFile("src/test/resources/json/jsonSchema.json"); + JsonSchemaProvider schemaProvider = new JsonSchemaProvider(config); + schemaProvider.loadSchema(testSchema, schemaProvider.getLatestSchemaVersion()); + + Set edgeSchemaList = + schemaProvider.getEdgeSchemaForSourceTarget("tosca.nodes.LoadBalancer", + "tosca.nodes.Database", + schemaProvider.getLatestSchemaVersion()); + + // Validate edge schema + assertTrue(edgeSchemaList.size() == 2); + + for (EdgeSchema es : edgeSchemaList) { + System.out.println(es.toString()); + if (es.getName().equals("tosca.relationships.Uses")) { + assertTrue(es.getSource().equals("tosca.nodes.LoadBalancer")); + assertTrue(es.getTarget().equals("tosca.nodes.Database")); + assertTrue(es.getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_MANY)); + } + else if (es.getName().equals("tosca.relationships.RoutesTo")) { + assertTrue(es.getSource().equals("tosca.nodes.LoadBalancer")); + assertTrue(es.getTarget().equals("tosca.nodes.Database")); + assertTrue(es.getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_MANY)); + } + else { + assertTrue(false); + } + } + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testJsonSchemaWildcardEdges() { + try { + String testSchema = readFile("src/test/resources/json/jsonSchema.json"); + JsonSchemaProvider schemaProvider = new JsonSchemaProvider(config); + schemaProvider.loadSchema(testSchema, schemaProvider.getLatestSchemaVersion()); + + EdgeSchema edgeSchema = + schemaProvider.getEdgeSchema("amdocs.linkedTo", "service-instance", + "onap.nodes.sdwan.ManagementDomain", schemaProvider.getLatestSchemaVersion()); + + assertTrue(edgeSchema.getName().equals("amdocs.linkedTo")); + assertTrue(edgeSchema.getSource().equals("service-instance")); + assertTrue(edgeSchema.getTarget().equals("onap.nodes.sdwan.ManagementDomain")); + + edgeSchema = schemaProvider.getEdgeSchema("amdocs.linkedTo", "onap.nodes.sdwan.ManagementDomain", + "service-instance", schemaProvider.getLatestSchemaVersion()); + + assertTrue(edgeSchema == null); + + + edgeSchema = + schemaProvider.getEdgeSchema("amdocs.unknownRelationship", "unknown", + "onap.nodes.sdwan.ManagementDomain", schemaProvider.getLatestSchemaVersion()); + + assertTrue(edgeSchema.getName().equals("amdocs.unknownRelationship")); + assertTrue(edgeSchema.getSource().equals("unknown")); + assertTrue(edgeSchema.getTarget().equals("onap.nodes.sdwan.ManagementDomain")); + + edgeSchema = + schemaProvider.getEdgeSchema("amdocs.unknownRelationship", "onap.nodes.sdwan.ManagementDomain", + "unknown", schemaProvider.getLatestSchemaVersion()); + + assertTrue(edgeSchema.getName().equals("amdocs.unknownRelationship")); + assertTrue(edgeSchema.getSource().equals("onap.nodes.sdwan.ManagementDomain")); + assertTrue(edgeSchema.getTarget().equals("unknown")); + + Set edgeSchemaList = + schemaProvider.getEdgeSchemaForSourceTarget("service-instance", + "onap.nodes.sdwan.ManagementDomain", + schemaProvider.getLatestSchemaVersion()); + assertTrue(edgeSchemaList.size() == 1); + + edgeSchemaList = schemaProvider.getEdgeSchemaForSourceTarget("unknown", "unknown", + schemaProvider.getLatestSchemaVersion()); + assertTrue(edgeSchemaList.size() == 1); + + edgeSchemaList = schemaProvider.getEdgeSchemaForSourceTarget("service-instance", "service-instance", + schemaProvider.getLatestSchemaVersion()); + assertTrue(edgeSchemaList.size() == 1); + + + edgeSchemaList = schemaProvider.getAdjacentEdgeSchema("service-instance", schemaProvider.getLatestSchemaVersion()); + System.out.println("EDGE LIST: \n\n" + edgeSchemaList); + assertTrue(edgeSchemaList.size() == 8); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testInvalidVertexOrEdge() throws SchemaProviderException { + try { + String testSchema = readFile("src/test/resources/json/jsonSchema.json"); + JsonSchemaProvider schemaProvider = new JsonSchemaProvider(config); + schemaProvider.loadSchema(testSchema, schemaProvider.getLatestSchemaVersion()); + + VertexSchema vertSchema = + schemaProvider.getVertexSchema("bad-node", schemaProvider.getLatestSchemaVersion()); + assertTrue(vertSchema == null); + + EdgeSchema edgeSchema = schemaProvider.getEdgeSchema("org.onap.relationships.inventory.LocatedIn", + "cloud-region", "bad-node", schemaProvider.getLatestSchemaVersion()); + assertTrue(edgeSchema == null); + + Set edgeSchemaList = + schemaProvider.getAdjacentEdgeSchema("org.onap.nodes.bad-node", + schemaProvider.getLatestSchemaVersion()); + assertTrue(edgeSchemaList.isEmpty()); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testJsonSchemaListAttribute() { + try { + String testSchema = readFile("src/test/resources/json/jsonSchema.json"); + JsonSchemaProvider schemaProvider = new JsonSchemaProvider(config); + schemaProvider.loadSchema(testSchema, schemaProvider.getLatestSchemaVersion()); + + VertexSchema vertSchema = + schemaProvider.getVertexSchema("onap.nodes.sdwan.ManagementDomain", + schemaProvider.getLatestSchemaVersion()); + System.out.println(vertSchema.toString()); + + // Validate schema + PropertySchema propSchema = vertSchema.getPropertySchema("controllers"); + assertTrue(propSchema.getDataType().getType().compareTo(Type.LIST) == 0); + ListDataType listType = (ListDataType)propSchema.getDataType(); + assertTrue(listType.getListType().getType().compareTo(Type.STRING) == 0); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testJsonSchemaMapAttribute() { + try { + String testSchema = readFile("src/test/resources/json/jsonSchema.json"); + JsonSchemaProvider schemaProvider = new JsonSchemaProvider(config); + schemaProvider.loadSchema(testSchema, schemaProvider.getLatestSchemaVersion()); + + VertexSchema vertSchema = + schemaProvider.getVertexSchema("onap.nodes.sdwan.ManagementDomain", + schemaProvider.getLatestSchemaVersion()); + System.out.println(vertSchema.toString()); + + // Validate schema + PropertySchema propSchema = vertSchema.getPropertySchema("analyticClusters"); + assertTrue(propSchema.getDataType().getType().compareTo(Type.MAP) == 0); + MapDataType mapType = (MapDataType)propSchema.getDataType(); + assertTrue(mapType.getMapType().getType().compareTo(Type.STRING) == 0); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testJsonSchemaComplexAttribute() { + try { + String testSchema = readFile("src/test/resources/json/jsonSchema.json"); + JsonSchemaProvider schemaProvider = new JsonSchemaProvider(config); + schemaProvider.loadSchema(testSchema, schemaProvider.getLatestSchemaVersion()); + + VertexSchema vertSchema = + schemaProvider.getVertexSchema("org.onap.resource.extContrailCP", + schemaProvider.getLatestSchemaVersion()); + System.out.println(vertSchema.toString()); + + System.out.println("\n\nSize: " + vertSchema.getPropertySchemaList().size()); + System.out.println(vertSchema.getPropertySchemaList()); + assertTrue(vertSchema.getPropertySchemaList().size() == 22); + + // Validate property schema + PropertySchema propSchema = vertSchema.getPropertySchema("exCP_naming"); + assertTrue(propSchema.getDataType().getType().compareTo(Type.COMPLEX) == 0); + ComplexDataType complexType = (ComplexDataType)propSchema.getDataType(); + List complexProps = complexType.getSubProperties(); + assertTrue(complexProps.size() == 4); + + PropertySchema subProp = null; + for (PropertySchema p : complexProps) { + if (p.getName().equals("naming_policy")) { + subProp = p; + } + } + + assertTrue(!subProp.isRequired()); + assertTrue(subProp.getDataType().getType().compareTo(Type.STRING) == 0); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testParseSchemaServiceResponse() { + try { + String testSchema = readFile("src/test/resources/json/schemaServiceResponse.json"); + SchemaServiceResponse resp = SchemaServiceResponse.fromJson(testSchema); + + System.out.println(resp.toJson()); + assertTrue(resp.getVersion().equals("v1")); + + JsonSchema jsonSchema = resp.getData(); + System.out.println(jsonSchema.toJson()); + + assertTrue(jsonSchema.getDataTypes().size() == 1); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testSchemaValidateSuccess() { + try { + String testSchema = readFile("src/test/resources/json/schemaServiceResponse.json"); + SchemaServiceResponse schema = SchemaServiceResponse.fromJson(testSchema); + schema.getData().validate(); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test(expected = SchemaProviderException.class) + public void testSchemaValidateBadEdge() throws SchemaProviderException { + SchemaServiceResponse schema; + + try { + String testSchema = readFile("src/test/resources/json/badEdgeSchema.json"); + schema = SchemaServiceResponse.fromJson(testSchema); + } + catch (Exception ex) { + assertTrue(false); + return; + } + + schema.getData().validate(); + } + + @Test(expected = SchemaProviderException.class) + public void testSchemaValidateBadVertex() throws SchemaProviderException { + SchemaServiceResponse schema; + + try { + String testSchema = readFile("src/test/resources/json/badVertexSchema.json"); + schema = SchemaServiceResponse.fromJson(testSchema); + } + catch (Exception ex) { + assertTrue(false); + return; + } + + System.out.println("Validate"); + schema.getData().validate(); + System.out.println("Validate done"); + } + + @Test(expected = SchemaProviderException.class) + public void testSchemaValidateBadType() throws SchemaProviderException { + SchemaServiceResponse schema; + + try { + String testSchema = readFile("src/test/resources/json/badTypeSchema.json"); + schema = SchemaServiceResponse.fromJson(testSchema); + } + catch (Exception ex) { + assertTrue(false); + return; + } + + schema.getData().validate(); + } + + @Test(expected = SchemaProviderException.class) + public void testSchemaValidateBadProp() throws SchemaProviderException { + SchemaServiceResponse schema; + + try { + String testSchema = readFile("src/test/resources/json/badPropSchema.json"); + schema = SchemaServiceResponse.fromJson(testSchema); + } + catch (Exception ex) { + assertTrue(false); + return; + } + + schema.getData().validate(); + } + + static String readFile(String path) throws IOException { + byte[] encoded = Files.readAllBytes(Paths.get(path)); + return new String(encoded); + } +} diff --git a/aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/oxm/OxmSchemaProviderTest.java b/aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/oxm/OxmSchemaProviderTest.java new file mode 100644 index 00000000..6c7364ae --- /dev/null +++ b/aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/oxm/OxmSchemaProviderTest.java @@ -0,0 +1,254 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.oxm; + + +import static org.junit.Assert.assertTrue; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Set; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.aai.schemaif.SchemaProviderException; +import org.onap.aai.schemaif.definitions.EdgeSchema; +import org.onap.aai.schemaif.definitions.PropertySchema; +import org.onap.aai.schemaif.definitions.VertexSchema; +import org.onap.aai.schemaif.definitions.types.DataType.Type; + +@RunWith(MockitoJUnitRunner.Silent.class) +public class OxmSchemaProviderTest extends OxmSchemaServiceSetup { + + @Test + public void testLoadingSchema() throws SchemaProviderException { + try { + OxmSchemaProvider schemaProvider = new OxmSchemaProvider(); + schemaProvider.loadSchema(); + + VertexSchema vertSchema = schemaProvider.getVertexSchema("pserver", schemaProvider.getLatestSchemaVersion()); + System.out.println(vertSchema.toString()); + + EdgeSchema edgeSchema = schemaProvider.getEdgeSchema("org.onap.relationships.inventory.LocatedIn", + "cloud-region", "zone", schemaProvider.getLatestSchemaVersion()); + System.out.println(edgeSchema.toString()); + + // Validate vertex schema + assertTrue(vertSchema.getName().equals("pserver")); + assertTrue(vertSchema.getAnnotationValue("nameProps").equals("pserver-name2")); + assertTrue(vertSchema.getAnnotationValue("dependentOn") == null); + + PropertySchema propSchema = vertSchema.getPropertySchema("hostname"); + assertTrue(propSchema.getName().equals("hostname")); + assertTrue(propSchema.getDefaultValue().equals("")); + assertTrue(propSchema.isRequired()); + assertTrue(!propSchema.isKey()); + assertTrue(propSchema.getDataType().getType().compareTo(Type.STRING) == 0); + Object obj = propSchema.validateValue("somestring"); + assertTrue(obj instanceof String); + + propSchema = vertSchema.getPropertySchema("in-maint"); + assertTrue(propSchema.getName().equals("in-maint")); + assertTrue(propSchema.getDefaultValue().equals("false")); + assertTrue(!propSchema.isRequired()); + assertTrue(!propSchema.isKey()); + assertTrue(!propSchema.isReserved()); + assertTrue(propSchema.getDataType().getType().compareTo(Type.BOOL) == 0); + obj = propSchema.validateValue("True"); + assertTrue(obj instanceof Boolean); + obj = propSchema.validateValue("false"); + assertTrue(obj instanceof Boolean); + assertTrue(propSchema.getDataType().validateValue("badValue") == null); + + + propSchema = vertSchema.getPropertySchema("aai-node-type"); + assertTrue(propSchema.getName().equals("aai-node-type")); + assertTrue(propSchema.getDefaultValue().equals("")); + assertTrue(!propSchema.isRequired()); + assertTrue(!propSchema.isKey()); + assertTrue(propSchema.isReserved()); + assertTrue(propSchema.getDataType().getType().compareTo(Type.STRING) == 0); + + propSchema = vertSchema.getPropertySchema("pserver-id"); + assertTrue(propSchema.getName().equals("pserver-id")); + assertTrue(propSchema.getDefaultValue().equals("")); + assertTrue(propSchema.isRequired()); + assertTrue(!propSchema.isReserved()); + assertTrue(propSchema.isKey()); + assertTrue(propSchema.getDataType().getType().compareTo(Type.STRING) == 0); + + propSchema = vertSchema.getPropertySchema("number-of-cpus"); + assertTrue(propSchema.getName().equals("number-of-cpus")); + assertTrue(propSchema.getAnnotationValue("source-of-truth-type").equals("openstack")); + assertTrue(propSchema.getDataType().getType().compareTo(Type.INT) == 0); + obj = propSchema.validateValue("35"); + assertTrue(obj instanceof Integer); + obj = propSchema.validateValue("5.0"); + assertTrue(obj instanceof Integer); + assertTrue(propSchema.getDataType().validateValue("5.5") == null); + assertTrue(propSchema.getDataType().validateValue("xyz") == null); + + // Validate edge schema + assertTrue(edgeSchema.getName().equals("org.onap.relationships.inventory.LocatedIn")); + assertTrue(edgeSchema.getSource().equals("cloud-region")); + assertTrue(edgeSchema.getTarget().equals("zone")); + assertTrue(edgeSchema.getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_ONE)); + assertTrue(edgeSchema.getAnnotationValue("contains-other-v").equals("NONE")); + assertTrue(edgeSchema.getPropertySchema("prevent-delete").getDataType().getType().equals(Type.STRING)); + + // Validate 'dependentOn' annotation + vertSchema = schemaProvider.getVertexSchema("tenant", schemaProvider.getLatestSchemaVersion()); + assertTrue(vertSchema.getAnnotationValue("dependentOn").equals("cloud-region")); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testAdjacentEdges() throws SchemaProviderException { + try { + OxmSchemaProvider schemaProvider = new OxmSchemaProvider(); + schemaProvider.loadSchema(); + + Set edgeSchemaList = + schemaProvider.getAdjacentEdgeSchema("snapshot", schemaProvider.getLatestSchemaVersion()); + + // Validate edge schema + assertTrue(edgeSchemaList.size() == 2); + + for (EdgeSchema es : edgeSchemaList) { + System.out.println(es.toString()); + if (es.getName().equals("org.onap.relationships.inventory.BelongsTo")) { + assertTrue(es.getSource().equals("snapshot")); + assertTrue(es.getTarget().equals("cloud-region")); + assertTrue(es.getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_ONE)); + } + else if (es.getName().equals("org.onap.relationships.inventory.Uses")) { + assertTrue(es.getSource().equals("vserver")); + assertTrue(es.getTarget().equals("snapshot")); + assertTrue(es.getMultiplicity().equals(EdgeSchema.Multiplicity.ONE_2_ONE)); + } + else { + assertTrue(false); + } + } + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testValidSourceTargetEdge() throws SchemaProviderException { + try { + OxmSchemaProvider schemaProvider = new OxmSchemaProvider(); + schemaProvider.loadSchema(); + + Set edgeSchemaList = + schemaProvider.getEdgeSchemaForSourceTarget("service-instance", "customer", + schemaProvider.getLatestSchemaVersion()); + + // Validate edge schema + assertTrue(edgeSchemaList.size() == 1); + assertTrue(edgeSchemaList.iterator().next().getName().equals("ncso.related-to")); + assertTrue(edgeSchemaList.iterator().next().getSource().equals("service-instance")); + assertTrue(edgeSchemaList.iterator().next().getTarget().equals("customer")); + assertTrue(edgeSchemaList.iterator().next().getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_MANY)); + + edgeSchemaList = + schemaProvider.getEdgeSchemaForSourceTarget("cloud-region", "complex", + schemaProvider.getLatestSchemaVersion()); + + // Validate edge schema + assertTrue(edgeSchemaList.size() == 2); + + for (EdgeSchema es : edgeSchemaList) { + System.out.println(es.toString()); + if (es.getName().equals("org.onap.relationships.inventory.FoundIn")) { + assertTrue(es.getSource().equals("cloud-region")); + assertTrue(es.getTarget().equals("complex")); + assertTrue(es.getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_MANY)); + } + else if (es.getName().equals("org.onap.relationships.inventory.LocatedIn")) { + assertTrue(es.getSource().equals("cloud-region")); + assertTrue(es.getTarget().equals("complex")); + assertTrue(es.getMultiplicity().equals(EdgeSchema.Multiplicity.MANY_2_ONE)); + } + else { + assertTrue(false); + } + } + + edgeSchemaList = + schemaProvider.getEdgeSchemaForSourceTarget("cloud-region", "bad-node", + schemaProvider.getLatestSchemaVersion()); + + // Validate edge schema + assertTrue(edgeSchemaList.size() == 0); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } + + @Test + public void testInvalidVertexOrEdge() throws SchemaProviderException { + try { + OxmSchemaProvider schemaProvider = new OxmSchemaProvider(); + schemaProvider.loadSchema(); + + VertexSchema vertSchema = + schemaProvider.getVertexSchema("bad-node", schemaProvider.getLatestSchemaVersion()); + assertTrue(vertSchema == null); + + EdgeSchema edgeSchema = schemaProvider.getEdgeSchema("org.onap.relationships.inventory.LocatedIn", + "cloud-region", "bad-node", schemaProvider.getLatestSchemaVersion()); + assertTrue(edgeSchema == null); + + Set edgeSchemaList = + schemaProvider.getAdjacentEdgeSchema("org.onap.nodes.bad-node", + schemaProvider.getLatestSchemaVersion()); + assertTrue(edgeSchemaList.isEmpty()); + } + catch (Exception ex) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + ex.printStackTrace(printWriter); + System.out.println(writer.toString()); + assertTrue(false); + } + } +} diff --git a/aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/oxm/OxmSchemaServiceSetup.java b/aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/oxm/OxmSchemaServiceSetup.java new file mode 100644 index 00000000..b4c1ca2e --- /dev/null +++ b/aai-schema-abstraction/src/test/java/org/onap/aai/schemaif/oxm/OxmSchemaServiceSetup.java @@ -0,0 +1,78 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.schemaif.oxm; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.junit.Before; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.onap.aai.edges.EdgeIngestor; +import org.onap.aai.nodes.NodeIngestor; +import org.onap.aai.setup.AAIConfigTranslator; +import org.onap.aai.setup.SchemaLocationsBean; +import org.onap.aai.setup.SchemaVersion; +import org.onap.aai.setup.SchemaConfigVersions; +import org.onap.aai.setup.Translator; + +public class OxmSchemaServiceSetup { + + @Mock + private SchemaLocationsBean schemaLocationsBean; + + @Mock + private SchemaConfigVersions schemaConfigVersions; + + private EdgePropsConfiguration edgePropsConfiguration = new EdgePropsConfiguration(); + + private List schemaVersionList = new ArrayList<>(); + + private OxmEdgeRulesLoader edgeLoader; + private OxmSchemaLoader vertexLoader; + + @Before + public void schemaBeanMockSetup() throws Exception { + schemaVersionList.add(new SchemaVersion("v13")); + + Mockito.when(schemaConfigVersions.getVersions()).thenReturn(schemaVersionList); + Mockito.when(schemaLocationsBean.getNodesInclusionPattern()).thenReturn(Arrays.asList(".*oxm(.*).xml")); + Mockito.when(schemaLocationsBean.getEdgesInclusionPattern()).thenReturn(Arrays.asList("DbEdgeRules_.*.json")); + Mockito.when(schemaLocationsBean.getNodeDirectory()).thenReturn("src/test/resources/oxm/oxm"); + Mockito.when(schemaLocationsBean.getEdgeDirectory()).thenReturn("src/test/resources/oxm/edge-rules"); + + AAIConfigTranslator aaiConfigTranslator = new AAIConfigTranslator(schemaLocationsBean, schemaConfigVersions); + Set translators = new HashSet<>(); + translators.add(aaiConfigTranslator); + NodeIngestor nodeIngestor = new NodeIngestor(translators); + nodeIngestor.initialize(); + EdgeIngestor edgeIngestor = new EdgeIngestor(translators); + edgeIngestor.initialize(); + + edgePropsConfiguration.setEdgePropsDir("src/test/resources/oxm/edge-props"); + edgeLoader = new OxmEdgeRulesLoader(aaiConfigTranslator, edgeIngestor, edgePropsConfiguration); + vertexLoader = new OxmSchemaLoader(aaiConfigTranslator, nodeIngestor); + } + +} diff --git a/aai-schema-abstraction/src/test/resources/json/badEdgeSchema.json b/aai-schema-abstraction/src/test/resources/json/badEdgeSchema.json new file mode 100644 index 00000000..66892d3a --- /dev/null +++ b/aai-schema-abstraction/src/test/resources/json/badEdgeSchema.json @@ -0,0 +1,100 @@ +{ + "schema-version": "v1", + "schema-type": "json", + "schema-content": { + "relationship_types": [ + { + "from": "tosca.nodes.SoftwareComponent", + "label": "tosca.relationships.HostedOn", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + } + ], + "data_types": [ + { + "name": "org.onap.datatypes.network.MacAssignments", + "description": "", + "properties": [ + { + "name": "mac_range_plan", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "mac_count", + "required": false, + "type": "integer", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "supplemental_data", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + } + ] + } + ], + "node_types": [ + { + "name": "tosca.nodes.ObjectStorage", + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "name", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": true, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "size", + "required": true, + "unique": false, + "type": "integer", + "description": "", + "default": "50", + "annotations": { + "indexed": false, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + }, + { + "name": "maxsize", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + } + ] + } + ] + } +} \ No newline at end of file diff --git a/aai-schema-abstraction/src/test/resources/json/badPropSchema.json b/aai-schema-abstraction/src/test/resources/json/badPropSchema.json new file mode 100644 index 00000000..5c24fce0 --- /dev/null +++ b/aai-schema-abstraction/src/test/resources/json/badPropSchema.json @@ -0,0 +1,101 @@ +{ + "schema-version": "v1", + "schema-type": "json", + "schema-content": { + "relationship_types": [ + { + "from": "tosca.nodes.SoftwareComponent", + "to": "tosca.nodes.Compute", + "label": "tosca.relationships.HostedOn", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + } + ], + "data_types": [ + { + "name": "org.onap.datatypes.network.MacAssignments", + "description": "", + "properties": [ + { + "name": "mac_range_plan", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "mac_count", + "required": false, + "type": "integer", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "supplemental_data", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + } + ] + } + ], + "node_types": [ + { + "name": "tosca.nodes.ObjectStorage", + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": true, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "size", + "required": true, + "unique": false, + "type": "integer", + "description": "", + "default": "50", + "annotations": { + "indexed": false, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + }, + { + "name": "maxsize", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + } + ] + } + ] + } +} \ No newline at end of file diff --git a/aai-schema-abstraction/src/test/resources/json/badTypeSchema.json b/aai-schema-abstraction/src/test/resources/json/badTypeSchema.json new file mode 100644 index 00000000..c987a840 --- /dev/null +++ b/aai-schema-abstraction/src/test/resources/json/badTypeSchema.json @@ -0,0 +1,101 @@ +{ + "schema-version": "v1", + "schema-type": "json", + "schema-content": { + "relationship_types": [ + { + "from": "tosca.nodes.SoftwareComponent", + "to": "tosca.nodes.Compute", + "label": "tosca.relationships.HostedOn", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + } + ], + "data_types": [ + { + "name": "", + "description": "", + "properties": [ + { + "name": "mac_range_plan", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "mac_count", + "required": false, + "type": "integer", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "supplemental_data", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + } + ] + } + ], + "node_types": [ + { + "name": "tosca.nodes.ObjectStorage", + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "name", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": true, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "size", + "required": true, + "unique": false, + "type": "integer", + "description": "", + "default": "50", + "annotations": { + "indexed": false, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + }, + { + "name": "maxsize", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + } + ] + } + ] + } +} \ No newline at end of file diff --git a/aai-schema-abstraction/src/test/resources/json/badVertexSchema.json b/aai-schema-abstraction/src/test/resources/json/badVertexSchema.json new file mode 100644 index 00000000..cd8bd3d7 --- /dev/null +++ b/aai-schema-abstraction/src/test/resources/json/badVertexSchema.json @@ -0,0 +1,100 @@ +{ + "schema-version": "v1", + "schema-type": "json", + "schema-content": { + "relationship_types": [ + { + "from": "tosca.nodes.SoftwareComponent", + "to": "tosca.nodes.Compute", + "label": "tosca.relationships.HostedOn", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + } + ], + "data_types": [ + { + "name": "org.onap.datatypes.network.MacAssignments", + "description": "", + "properties": [ + { + "name": "mac_range_plan", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "mac_count", + "required": false, + "type": "integer", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "supplemental_data", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + } + ] + } + ], + "node_types": [ + { + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "name", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": true, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "size", + "required": true, + "unique": false, + "type": "integer", + "description": "", + "default": "50", + "annotations": { + "indexed": false, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + }, + { + "name": "maxsize", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + } + ] + } + ] + } +} \ No newline at end of file diff --git a/aai-schema-abstraction/src/test/resources/json/jsonSchema.json b/aai-schema-abstraction/src/test/resources/json/jsonSchema.json new file mode 100644 index 00000000..36db8bbd --- /dev/null +++ b/aai-schema-abstraction/src/test/resources/json/jsonSchema.json @@ -0,0 +1,976 @@ +{ + "relationship_types": [ + { + "from": "service-instance", + "to": "*", + "label": "amdocs.linkedTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "unknown", + "to": "*", + "label": "amdocs.unknownRelationship", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "*", + "to": "unknown", + "label": "amdocs.unknownRelationship", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.SoftwareComponent", + "to": "tosca.nodes.Compute", + "label": "tosca.relationships.HostedOn", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.LoadBalancer", + "to": "tosca.nodes.ObjectStorage", + "label": "tosca.relationships.RoutesTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.LoadBalancer", + "to": "onap.nodes.sdwan.ManagementDomain", + "label": "tosca.relationships.RoutesTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.LoadBalancer", + "to": "tosca.nodes.LoadBalancer", + "label": "tosca.relationships.RoutesTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.LoadBalancer", + "to": "tosca.nodes.Database", + "label": "tosca.relationships.RoutesTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.LoadBalancer", + "to": "tosca.nodes.Compute", + "label": "tosca.relationships.RoutesTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.LoadBalancer", + "to": "tosca.nodes.Database", + "label": "tosca.relationships.Uses", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.LoadBalancer", + "to": "tosca.nodes.WebApplication", + "label": "tosca.relationships.RoutesTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.LoadBalancer", + "to": "tosca.nodes.WebServer", + "label": "tosca.relationships.RoutesTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "nodes.ics.Port", + "to": "tosca.nodes.Compute", + "label": "tosca.relationships.network.BindsTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.network.Port", + "to": "tosca.nodes.Compute", + "label": "tosca.relationships.network.BindsTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.Compute", + "to": "tosca.nodes.BlockStorage", + "label": "tosca.relationships.AttachesTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "onap.nodes.sdwan.RoutingInstance", + "to": "onap.nodes.sdwan.service.SubscriberService", + "label": "onap.relationships.sdwan.BelongsTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "onap.nodes.sdwan.RoutingInstance", + "to": "onap.nodes.sdwan.ManagementDomain", + "label": "onap.relationships.ManagedBy", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "tosca.nodes.Database", + "to": "tosca.nodes.DBMS", + "label": "tosca.relationships.HostedOn", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "onap.nodes.sdwan.uCPE", + "to": "onap.nodes.sdwan.service.SubscriberService", + "label": "onap.relationships.sdwan.BelongsTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "onap.nodes.sdwan.uCPE", + "to": "onap.nodes.sdwan.ManagementDomain", + "label": "onap.relationships.ManagedBy", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "onap.nodes.sdwan.VPN", + "to": "onap.nodes.sdwan.service.SubscriberService", + "label": "onap.relationships.sdwan.BelongsTo", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + }, + { + "from": "onap.nodes.sdwan.Account", + "to": "onap.nodes.sdwan.ManagementDomain", + "label": "onap.relationships.ManagedBy", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + } + ], + "data_types": [ + { + "name": "org.onap.datatypes.network.VlanRequirements", + "description": "", + "properties": [ + { + "name": "vlan_range_plan", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "vlan_type", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "Valid_values: [c-tag, s-tag]," + }, + { + "name": "vlan_count", + "required": false, + "type": "integer", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "supplemental_data", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + } + ] + }, + { + "name": "org.onap.datatypes.RuleList", + "description": "", + "properties": [ + { + "name": "network_policy_entries_policy_rule", + "required": false, + "type": "list:string", + "description": "", + "default": "", + "constraint": "" + } + ] + }, + { + "name": "org.onap.datatypes.network.MacRequirements", + "description": "", + "properties": [ + { + "name": "mac_range_plan", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "mac_count", + "required": false, + "type": "integer", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "mac_count_required", + "required": false, + "type": "org.onap.datatypes.AssignmentRequirements", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "supplemental_data", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + } + ] + }, + { + "name": "org.onap.datatypes.AssignmentRequirements", + "description": "", + "properties": [ + { + "name": "is_required", + "required": false, + "type": "boolean", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "count", + "required": false, + "type": "integer", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "supplemental_data", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + } + ] + }, + { + "name": "org.onap.datatypes.Naming", + "description": "", + "properties": [ + { + "name": "generated_naming", + "required": false, + "type": "boolean", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "naming_policy", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "instance_name", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "supplemental_data", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + } + ] + } + ], + "node_types": [ + { + "name": "unknown", + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "node-name", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": true, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "" + } + } + ] + }, + { + "name": "service-instance", + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "service-instance-name", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": true, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "service-type", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + } + ] + }, + { + "name": "tosca.nodes.ObjectStorage", + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "name", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": true, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "size", + "required": true, + "unique": false, + "type": "integer", + "description": "", + "default": "50", + "annotations": { + "indexed": false, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + }, + { + "name": "maxsize", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + } + ] + }, + { + "name": "org.onap.resource.NetworkRules", + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "name", + "required": false, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "network_policy_entries", + "required": false, + "unique": false, + "type": "org.onap.datatypes.RuleList", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + } + ] + }, + { + "name": "onap.nodes.sdwan.ManagementDomain", + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "mdName", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "controllers", + "required": true, + "unique": false, + "type": "list:string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "stagingControllers", + "required": true, + "unique": false, + "type": "list:string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "mdDirectorUrl", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "mdDirectorCredentialName", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "encryptionType", + "required": false, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "analyticClusters", + "required": false, + "unique": false, + "type": "map:string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "cliUsers", + "required": false, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "devicesSet", + "required": false, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + } + ] + }, + { + "name": "org.onap.resource.extContrailCP", + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "static_routes", + "required": false, + "unique": false, + "type": "list:string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "virtual_network", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "static_route", + "required": false, + "unique": false, + "type": "boolean", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "allowed_address_pairs", + "required": false, + "unique": false, + "type": "list:string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "shared_ip", + "required": false, + "unique": false, + "type": "boolean", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "interface_type", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "Valid_values: [management, left, right, other]," + } + }, + { + "name": "network_role", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "network_role_tag", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "mac_requirements", + "required": false, + "unique": false, + "type": "org.onap.datatypes.network.MacRequirements", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "vlan_requirements", + "required": false, + "unique": false, + "type": "list:string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "ip_requirements", + "required": true, + "unique": false, + "type": "list:string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "exCP_naming", + "required": true, + "unique": false, + "type": "org.onap.datatypes.Naming", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "subnetpoolid", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "subinterface_indicator", + "required": false, + "unique": false, + "type": "boolean", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "related_networks", + "required": false, + "unique": false, + "type": "list:string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "ip_address", + "required": false, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "order", + "required": true, + "unique": false, + "type": "integer", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0," + } + }, + { + "name": "is_default", + "required": false, + "unique": false, + "type": "boolean", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "ip_range_start", + "required": false, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "ip_range_end", + "required": false, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + } + ] + } + ], + "common_node_properties": [ + { + "name": "aai-uuid", + "required": true, + "unique": true, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": true, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "source-of-truth", + "required": false, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + } + ] +} \ No newline at end of file diff --git a/aai-schema-abstraction/src/test/resources/json/schemaServiceResponse.json b/aai-schema-abstraction/src/test/resources/json/schemaServiceResponse.json new file mode 100644 index 00000000..06e78ed1 --- /dev/null +++ b/aai-schema-abstraction/src/test/resources/json/schemaServiceResponse.json @@ -0,0 +1,131 @@ +{ + "schema-version": "v1", + "schema-type": "json", + "schema-content": { + "relationship_types": [ + { + "from": "tosca.nodes.SoftwareComponent", + "to": "tosca.nodes.Compute", + "label": "tosca.relationships.HostedOn", + "annotations": { + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE" + } + } + ], + "data_types": [ + { + "name": "org.onap.datatypes.network.MacAssignments", + "description": "", + "properties": [ + { + "name": "mac_range_plan", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "mac_count", + "required": false, + "type": "integer", + "description": "", + "default": "", + "constraint": "" + }, + { + "name": "supplemental_data", + "required": false, + "type": "string", + "description": "", + "default": "", + "constraint": "" + } + ] + } + ], + "node_types": [ + { + "name": "tosca.nodes.ObjectStorage", + "description": "", + "uriTemplate": "", + "properties": [ + { + "name": "name", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": true, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "size", + "required": true, + "unique": false, + "type": "integer", + "description": "", + "default": "50", + "annotations": { + "indexed": false, + "searchable": true, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + }, + { + "name": "maxsize", + "required": true, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "Greater_or_equal: 0 GB," + } + } + ] + } + ], + "common_node_properties": [ + { + "name": "aai-uuid", + "required": true, + "unique": true, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": true, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + }, + { + "name": "source-of-truth", + "required": false, + "unique": false, + "type": "string", + "description": "", + "default": "", + "annotations": { + "indexed": false, + "searchable": false, + "source_of_truth_type": "AAI", + "constraint": "" + } + } + ] + } +} \ No newline at end of file diff --git a/aai-schema-abstraction/src/test/resources/oxm/edge-props/edge_properties_v13.json b/aai-schema-abstraction/src/test/resources/oxm/edge-props/edge_properties_v13.json new file mode 100644 index 00000000..8d00636d --- /dev/null +++ b/aai-schema-abstraction/src/test/resources/oxm/edge-props/edge_properties_v13.json @@ -0,0 +1,6 @@ +{ + "contains-other-v": "java.lang.String", + "delete-other-v": "java.lang.String", + "SVC-INFRA": "java.lang.String", + "prevent-delete": "java.lang.String" +} \ No newline at end of file diff --git a/aai-schema-abstraction/src/test/resources/oxm/edge-rules/v13/DbEdgeRules_v13.json b/aai-schema-abstraction/src/test/resources/oxm/edge-rules/v13/DbEdgeRules_v13.json new file mode 100644 index 00000000..75365661 --- /dev/null +++ b/aai-schema-abstraction/src/test/resources/oxm/edge-rules/v13/DbEdgeRules_v13.json @@ -0,0 +1,2848 @@ +{ + "rules": [ + { + "from": "service-instance", + "to": "customer", + "label": "ncso.related-to", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" +}, +{ + "from": "generic-vnf", + "to": "vnfc", + "label": "ncso.related-to", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" +}, +{ + "from": "vnfc", + "to": "vnfc", + "label": "ncso.related-to", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" +}, +{ + "from": "vnfc", + "to": "vserver", + "label": "ncso.related-to", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" +}, +{ + "from": "generic-vnf", + "to": "service-instance", + "label": "ncso.related-to", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" +}, +{ + "from": "generic-vnf", + "to": "generic-vnf", + "label": "ncso.related-to", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, +{ + "from": "service-instance", + "to": "generic-vnf", + "label": "ncso.related-to", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" +}, +{ + "from": "generic-vnf", + "to": "vserver", + "label": "ncso.related-to", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" +}, + { + "from": "allotted-resource", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.PartOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "allotted-resource", + "to": "instance-group", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "allotted-resource", + "to": "l3-network", + "label": "org.onap.relationships.inventory.PartOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "allotted-resource", + "to": "l-interface", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "allotted-resource", + "to": "network-policy", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "allotted-resource", + "to": "vlan", + "label": "org.onap.relationships.inventory.PartOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "allotted-resource", + "to": "vpn-binding", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "tunnel-xconnect", + "to": "allotted-resource", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "availability-zone", + "to": "complex", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "availability-zone", + "to": "service-capability", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "availability-zone", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "cloud-region", + "to": "complex", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "cloud-region", + "to": "complex", + "label": "org.onap.relationships.inventory.FoundIn", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "cloud-region", + "to": "l3-network", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "cloud-region", + "to": "zone", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "dvs-switch", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "flavor", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "group-assignment", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "image", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "oam-network", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "snapshot", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "tenant", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vip-ipv4-address-list", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vip-ipv6-address-list", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "volume-group", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "complex", + "to": "l3-network", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "ctag-pool", + "to": "complex", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "configuration", + "to": "allotted-resource", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "configuration", + "to": "logical-link", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "metadatum", + "to": "configuration", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "connector", + "to": "virtual-data-center", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "metadatum", + "to": "connector", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "element-choice-set", + "to": "constrained-element-set", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "ctag-pool", + "to": "availability-zone", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "service-subscription", + "to": "customer", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "dvs-switch", + "to": "availability-zone", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "model-element", + "to": "element-choice-set", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "entitlement", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "availability-zone", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "complex", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "configuration", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "ctag-pool", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "instance-group", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "ipsec-configuration", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "l3-network", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "pnf", + "label": "tosca.relationships.HostedOn", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "pserver", + "label": "tosca.relationships.HostedOn", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vnfc", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "vnf-image", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "volume-group", + "label": "org.onap.relationships.inventory.DependsOn", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "vserver", + "label": "tosca.relationships.HostedOn", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "lag-interface", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "license", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l-interface", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "network-profile", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.ComposedOf", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "site-pair-set", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vf-module", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "pserver", + "to": "group-assignment", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "${direction}", + "default": "true", + "description":"" + }, + { + "from": "tenant", + "to": "group-assignment", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "metadatum", + "to": "image", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "instance-group", + "to": "model", + "label": "org.onap.relationships.inventory.Targets", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vig-server", + "to": "ipsec-configuration", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv4-address-list", + "to": "instance-group", + "label": "org.onap.relationships.inventory.network.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv4-address-list", + "to": "l3-network", + "label": "org.onap.relationships.inventory.network.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv4-address-list", + "to": "subnet", + "label": "org.onap.relationships.inventory.network.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv6-address-list", + "to": "instance-group", + "label": "org.onap.relationships.inventory.network.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv6-address-list", + "to": "l3-network", + "label": "org.onap.relationships.inventory.network.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv6-address-list", + "to": "subnet", + "label": "org.onap.relationships.inventory.network.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "ctag-assignment", + "to": "l3-network", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-network", + "to": "instance-group", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-network", + "to": "network-policy", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-network", + "to": "route-table-reference", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-network", + "to": "vpn-binding", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "segmentation-assignment", + "to": "l3-network", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "l3-network", + "label": "org.onap.relationships.inventory.ComposedOf", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "subnet", + "to": "l3-network", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "lag-interface", + "to": "lag-link", + "label": "tosca.relationships.network.LinksTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "lag-interface", + "to": "logical-link", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "lag-interface", + "to": "p-interface", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l-interface", + "to": "lag-interface", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "lag-interface", + "to": "l-interface", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "false", + "description":"" + }, + { + "from": "line-of-business", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv4-address-list", + "to": "l-interface", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv6-address-list", + "to": "l-interface", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l-interface", + "to": "instance-group", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l-interface", + "to": "l-interface", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l-interface", + "to": "logical-link", + "label": "tosca.relationships.network.LinksTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "logical-link", + "to": "l-interface", + "label": "org.onap.relationships.inventory.Source", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "false", + "description":"" + }, + { + "from": "logical-link", + "to": "l-interface", + "label": "org.onap.relationships.inventory.Destination", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "false", + "description":"" + }, + { + "from": "sriov-vf", + "to": "l-interface", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vlan", + "to": "l-interface", + "label": "tosca.relationships.network.LinksTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "logical-link", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "logical-link", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.BridgedTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "logical-link", + "to": "lag-link", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "logical-link", + "to": "logical-link", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "logical-link", + "to": "pnf", + "label": "org.onap.relationships.inventory.BridgedTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "logical-link", + "to": "pserver", + "label": "org.onap.relationships.inventory.BridgedTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "logical-link", + "to": "vpn-binding", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "model-ver", + "to": "model", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "constrained-element-set", + "to": "model-constraint", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "constrained-element-set", + "to": "model-element", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "model-constraint", + "to": "model-element", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "model-element", + "to": "model-element", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "model-element", + "to": "model-ver", + "label": "org.onap.relationships.inventory.IsA", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "metadatum", + "to": "model-ver", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "model-element", + "to": "model-ver", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "named-query", + "to": "model", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "named-query-element", + "to": "named-query", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "named-query-element", + "to": "model", + "label": "org.onap.relationships.inventory.IsA", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "named-query-element", + "to": "named-query-element", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "property-constraint", + "to": "named-query-element", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "related-lookup", + "to": "named-query-element", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l-interface", + "to": "newvce", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "oam-network", + "to": "complex", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "oam-network", + "to": "service-capability", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "operational-environment", + "to": "operational-environment", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "owning-entity", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l-interface", + "to": "p-interface", + "label": "tosca.relationships.network.BindsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "p-interface", + "to": "logical-link", + "label": "tosca.relationships.network.LinksTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "p-interface", + "to": "physical-link", + "label": "tosca.relationships.network.LinksTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "sriov-pf", + "to": "p-interface", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "platform", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "lag-interface", + "to": "pnf", + "label": "tosca.relationships.network.BindsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "p-interface", + "to": "pnf", + "label": "tosca.relationships.network.BindsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "pnf", + "to": "complex", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "pnf", + "to": "instance-group", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "pnf", + "to": "zone", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "cvlan-tag", + "to": "port-group", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "project", + "to": "service-instance", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "lag-interface", + "to": "pserver", + "label": "tosca.relationships.network.BindsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "p-interface", + "to": "pserver", + "label": "tosca.relationships.network.BindsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "pserver", + "to": "availability-zone", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "pserver", + "to": "cloud-region", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "pserver", + "to": "complex", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "pserver", + "to": "zone", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "site-pair", + "to": "routing-instance", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "allotted-resource", + "to": "service-instance", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "metadatum", + "to": "service-instance", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "allotted-resource", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "configuration", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "connector", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "ctag-assignment", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "cvlan-tag", + "label": "org.onap.relationships.inventory.ComposedOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "instance-group", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "logical-link", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "pnf", + "label": "org.onap.relationships.inventory.ComposedOf", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "service-instance", + "label": "org.onap.relationships.inventory.ComposedOf", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "vlan", + "label": "org.onap.relationships.inventory.ComposedOf", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "zone", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "service-subscription", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "class-of-service", + "to": "site-pair", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "routing-instance", + "to": "site-pair-set", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "sriov-vf", + "to": "sriov-pf", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "host-route", + "to": "subnet", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-subscription", + "to": "tenant", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "tenant", + "to": "l3-network", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vserver", + "to": "tenant", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "entitlement", + "to": "vce", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "license", + "to": "vce", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "port-group", + "to": "vce", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "vce", + "label": "org.onap.relationships.inventory.ComposedOf", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vce", + "to": "availability-zone", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vce", + "to": "complex", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vce", + "to": "vserver", + "label": "tosca.relationships.HostedOn", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vf-module", + "to": "l3-network", + "label": "org.onap.relationships.inventory.DependsOn", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vf-module", + "to": "vnfc", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "${direction}", + "default": "true", + "description":"" + }, + { + "from": "vf-module", + "to": "volume-group", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vip-ipv4-address-list", + "to": "instance-group", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vip-ipv4-address-list", + "to": "subnet", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vip-ipv6-address-list", + "to": "instance-group", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vip-ipv6-address-list", + "to": "subnet", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "virtual-data-center", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "logical-link", + "to": "virtual-data-center", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv4-address-list", + "to": "vlan", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv6-address-list", + "to": "vlan", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vlan", + "to": "logical-link", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vlan", + "to": "multicast-configuration", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv4-address-list", + "to": "vnfc", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-interface-ipv6-address-list", + "to": "vnfc", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vnfc", + "to": "instance-group", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vnfc", + "to": "vip-ipv4-address-list", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vnfc", + "to": "vip-ipv6-address-list", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "tenant", + "to": "volume-group", + "label": "org.onap.relationships.inventory.DependsOn", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "volume-group", + "to": "complex", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "lag-interface", + "to": "vpls-pe", + "label": "tosca.relationships.network.BindsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "p-interface", + "to": "vpls-pe", + "label": "tosca.relationships.network.BindsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vpls-pe", + "to": "complex", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vpls-pe", + "to": "ctag-pool", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "route-target", + "to": "vpn-binding", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l-interface", + "to": "vserver", + "label": "tosca.relationships.network.BindsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vf-module", + "to": "vserver", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vnfc", + "to": "vserver", + "label": "tosca.relationships.HostedOn", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vserver", + "to": "flavor", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vserver", + "to": "image", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vserver", + "to": "pserver", + "label": "tosca.relationships.HostedOn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "vserver", + "to": "snapshot", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vserver", + "to": "volume", + "label": "tosca.relationships.AttachesTo", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "${direction}", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "zone", + "to": "complex", + "label": "org.onap.relationships.inventory.LocatedIn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "allotted-resource", + "to": "model-ver", + "label": "org.onap.relationships.inventory.IsA", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "model-ver", + "label": "org.onap.relationships.inventory.IsA", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "l3-network", + "to": "model-ver", + "label": "org.onap.relationships.inventory.IsA", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "logical-link", + "to": "model-ver", + "label": "org.onap.relationships.inventory.IsA", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "model-ver", + "label": "org.onap.relationships.inventory.IsA", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vf-module", + "to": "model-ver", + "label": "org.onap.relationships.inventory.IsA", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "configuration", + "to": "l-interface", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "configuration", + "to": "pnf", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "forwarder", + "to": "forwarding-path", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "forwarding-path", + "to": "service-instance", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "forwarder", + "to": "l-interface", + "label": "org.onap.relationships.inventory.ForwardsTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "forwarder", + "to": "configuration", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "forwarding-path", + "to": "configuration", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "forwarder", + "to": "lag-interface", + "label": "org.onap.relationships.inventory.ForwardsTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "evc", + "to": "configuration", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "forwarder-evc", + "to": "configuration", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "forwarder", + "to": "p-interface", + "label": "org.onap.relationships.inventory.ForwardsTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "generic-vnf", + "to": "nos-server", + "label": "tosca.relationships.HostedOn", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "nos-server", + "to": "pserver", + "label": "tosca.relationships.HostedOn", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "nos-server", + "to": "tenant", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "NONE", + "prevent-delete": "!${direction}", + "default": "true", + "description":"" + }, + { + "from": "configuration", + "to": "configuration", + "label": "tosca.relationships.network.BindsTo", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "configuration", + "to": "vpn-binding", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "configuration", + "to": "l3-network", + "label": "org.onap.relationships.inventory.PartOf", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "vpn-binding", + "to": "customer", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description":"" + }, + { + "from": "service-instance", + "to": "configuration", + "label": "org.onap.relationships.inventory.ComposedOf", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "false", + "description":"" + }, + { + "from": "forwarder", + "to": "generic-vnf", + "label": "org.onap.relationships.inventory.AppliesTo", + "direction": "OUT", + "multiplicity": "MANY2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description": "Points to the generic-vnf(s) involved in this forwarding step." + }, + { + "from": "cloud-region", + "to": "instance-group", + "label": "org.onap.relationships.inventory.Uses", + "direction": "OUT", + "multiplicity": "ONE2MANY", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description": "" + }, + { + "from": "collection", + "to": "instance-group", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description": "" + }, + { + "from": "service-instance", + "to": "collection", + "label": "org.onap.relationships.inventory.MemberOf", + "direction": "OUT", + "multiplicity": "ONE2ONE", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "prevent-delete": "NONE", + "default": "true", + "description": "" + }, + { + "from": "vlan-mapping", + "to": "forwarder-evc", + "label": "org.onap.relationships.inventory.BelongsTo", + "direction": "OUT", + "multiplicity": "MANY2ONE", + "contains-other-v": "!${direction}", + "delete-other-v": "!${direction}", + "prevent-delete": "NONE", + "default": "true", + "description": "" + } + ] +} \ No newline at end of file diff --git a/aai-schema-abstraction/src/test/resources/oxm/oxm/v13/aai_oxm_v13.xml b/aai-schema-abstraction/src/test/resources/oxm/oxm/v13/aai_oxm_v13.xml new file mode 100644 index 00000000..bb786a35 --- /dev/null +++ b/aai-schema-abstraction/src/test/resources/oxm/oxm/v13/aai_oxm_v13.xml @@ -0,0 +1,6775 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit 1.2.3-korg