aboutsummaryrefslogtreecommitdiffstats
path: root/aai-schema-abstraction/src/main/java/org/onap
diff options
context:
space:
mode:
Diffstat (limited to 'aai-schema-abstraction/src/main/java/org/onap')
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProvider.java97
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProviderException.java47
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/SchemaProviderMsgs.java37
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/EdgeSchema.java116
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/PropertySchema.java100
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/VertexSchema.java65
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/BooleanDataType.java38
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/ComplexDataType.java58
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/DataType.java53
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/FloatDataType.java43
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/IntDataType.java54
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/ListDataType.java45
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/LongDataType.java43
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/MapDataType.java45
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/definitions/types/StringDataType.java35
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonEdgeSchema.java82
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonPropertySchema.java116
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/FromJsonVertexSchema.java132
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/JsonSchemaProvider.java235
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/JsonSchemaProviderConfig.java58
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaInstance.java121
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SchemaServiceResponse.java67
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/SecureClientHttpRequestFactory.java126
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/DataTypeDefinition.java125
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonEdgeSchema.java135
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonPropertySchema.java192
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonSchema.java167
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/json/definitions/JsonVertexSchema.java141
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/EdgePropsConfiguration.java42
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmEdgeSchema.java75
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmPropertySchema.java141
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/FromOxmVertexSchema.java95
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmEdgeRulesLoader.java246
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaLoader.java236
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/OxmSchemaProvider.java117
-rw-r--r--aai-schema-abstraction/src/main/java/org/onap/aai/schemaif/oxm/RelationshipSchema.java189
36 files changed, 3714 insertions, 0 deletions
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<EdgeSchema> 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<EdgeSchema> 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<String, VertexSchema> 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<String,String> annotations;
+ protected Map<String,PropertySchema> 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<String,PropertySchema> getPropertySchemaList() {
+ return properties;
+ }
+
+ public String getAnnotationValue(String annotation) {
+ return annotations.get(annotation.toLowerCase());
+ }
+
+ public Map<String,String> 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<String,String> 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<String, String> 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<String,PropertySchema> properties;
+ protected Map<String,String> annotations;
+
+ public String getName() {
+ return name;
+ }
+
+ public PropertySchema getPropertySchema(String propName) {
+ return properties.get(propName.toLowerCase());
+ }
+
+ public Map<String,PropertySchema> getPropertySchemaList() {
+ return properties;
+ }
+
+ public Map<String,String> 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<PropertySchema> subProperties;
+
+ public ComplexDataType(List<PropertySchema> subProperties) {
+ super(Type.COMPLEX);
+ this.subProperties = subProperties;
+ }
+
+ public List<PropertySchema> 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<String,String>();
+ if (jsonEdge.getAnnotations() != null) {
+ for (Map.Entry<String,String> entry : jsonEdge.getAnnotations().entrySet()) {
+ annotations.put(entry.getKey().toLowerCase(), entry.getValue());
+ }
+ }
+
+ // Currently edge properties are not supported in the json schema
+ properties = new HashMap<String,PropertySchema>();
+ }
+
+ 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<DataTypeDefinition> 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<String,String>();
+ if (pSchema.getAnnotations() != null) {
+ for (Map.Entry<String,String> entry : pSchema.getAnnotations().entrySet()) {
+ annotations.put(entry.getKey().toLowerCase(), entry.getValue());
+ }
+ }
+ }
+
+ private DataType resolveDataType(String typeString, List<DataTypeDefinition> 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<DataTypeDefinition> 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<PropertySchema> propList = new ArrayList<PropertySchema>();
+ 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<DataTypeDefinition> dataTypes, List<JsonPropertySchema> commonProps) throws SchemaProviderException {
+ name = jsonVertex.getName();
+ properties = new HashMap<String,PropertySchema>();
+ annotations = new HashMap<String,String>();
+
+ // 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<String,String> 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<String,String> propAnnotations = new HashMap<String,String>();
+ 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<String,SchemaInstance> 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<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException {
+ SchemaInstance inst = getSchemaVersion(version);
+
+ Set<EdgeSchema> edgeList = inst.getEdgeSchema(vertexType);
+ if (edgeList == null) {
+ edgeList = new HashSet<EdgeSchema>();
+ }
+
+ return edgeList;
+ }
+
+ @Override
+ public Set<EdgeSchema> 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<EdgeSchema> edgeList = inst.getEdgeSchemas(sourceType, targetType);
+ if (edgeList == null) {
+ edgeList = new HashSet<EdgeSchema>();
+ }
+
+ 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 <String> entity = new HttpEntity<String>(headers);
+
+ ResponseEntity<byte[]> 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<byte[]> 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<String, VertexSchema> 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<String, VertexSchema> vertexMap = new HashMap<>();
+
+ // source:target:type -> edge-schema
+ private Map<String, EdgeSchema> edgeKeyMap = new HashMap<>();
+
+ // source:target -> edge-schema
+ private Map<String, Set<EdgeSchema>> edgeSourceTargetMap = new HashMap<>();
+
+ // vertex-name -> edge-schema
+ private Map<String, Set<EdgeSchema>> 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<EdgeSchema> getEdgeSchemas(String source, String target) {
+ return edgeSourceTargetMap.get(source.toLowerCase() + ":" + target.toLowerCase());
+ }
+
+ public Set<EdgeSchema> 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<EdgeSchema> edgeListSource = vertexEdgeMap.get(e.getSource().toLowerCase());
+ Set<EdgeSchema> edgeListTarget = vertexEdgeMap.get(e.getTarget().toLowerCase());
+
+ if (edgeListSource == null) {
+ edgeListSource = new HashSet<EdgeSchema>();
+ }
+ if (edgeListTarget == null) {
+ edgeListTarget = new HashSet<EdgeSchema>();
+ }
+
+ 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<EdgeSchema> edgeList = edgeSourceTargetMap.get(sourceTargetKey);
+ if (edgeList == null) {
+ edgeList = new HashSet<EdgeSchema>();
+ }
+
+ 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<String, VertexSchema> 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<JsonPropertySchema> 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<JsonPropertySchema> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(List<JsonPropertySchema> 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<String,String> 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<String,String> getAnnotations() {
+ return annotations;
+ }
+ public void setAnnotations(Map<String,String> 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<String,String> 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<String,String> getAnnotations() {
+ return annotations;
+ }
+
+ public void setAnnotations(Map<String,String> 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<JsonEdgeSchema> relationshipTypes;
+
+ @SerializedName("node_types")
+ private List<JsonVertexSchema> nodeTypes;
+
+ @SerializedName("data_types")
+ private List<DataTypeDefinition> dataTypes;
+
+ @SerializedName("common_node_properties")
+ private List<JsonPropertySchema> commonNodeProps;
+
+
+ public void setRelationshipTypes(List<JsonEdgeSchema> relationshipTypes) {
+ this.relationshipTypes = relationshipTypes;
+ }
+
+ public void setNodeTypes(List<JsonVertexSchema> nodeTypes) {
+ this.nodeTypes = nodeTypes;
+ }
+
+ public void setDataTypes(List<DataTypeDefinition> dataTypes) {
+ this.dataTypes = dataTypes;
+ }
+
+ public List<JsonEdgeSchema> getRelationshipTypes() {
+ return relationshipTypes;
+ }
+
+ public List<JsonVertexSchema> getNodeTypes() {
+ return nodeTypes;
+ }
+
+ public List<DataTypeDefinition> getDataTypes() {
+ return dataTypes;
+ }
+
+ public List<JsonPropertySchema> getCommonProperties() {
+ return commonNodeProps;
+ }
+
+ public void setCommonProperties(List<JsonPropertySchema> 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<JsonPropertySchema> properties;
+ private Map<String,String> 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<JsonPropertySchema> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(List<JsonPropertySchema> properties) {
+ this.properties = properties;
+ }
+
+ public Map<String,String> getAnnotations() {
+ return annotations;
+ }
+
+ public void setAnnotations(Map<String,String> 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<String,String>();
+ properties = new HashMap<String,PropertySchema>();
+
+ // 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<String,String>();
+ Map<String, Object> oxmProps = mapping.getProperties();
+ for (Map.Entry<String, Object> 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<String,String>();
+
+ 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<String> 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<String, DynamicType> xmlElementLookup) throws SchemaProviderException {
+ name = vertexType;
+ properties = new HashMap<String,PropertySchema>();
+ annotations = new HashMap<String,String>();
+
+ 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<String, Object> oxmProps = modelObjectType.getDescriptor().getProperties();
+ for (Map.Entry<String, Object> 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<String, RelationshipSchema> 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<String, File> 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<String, File> 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<String, RelationshipSchema> 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<String, File> props) throws IOException, SchemaProviderException, EdgeRuleNotFoundException {
+
+ Multimap<String, EdgeRule> 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<String, File> edgePropertyFiles(EdgePropsConfiguration edgePropsConfiguration)
+ throws SchemaProviderException {
+ Map<String, File> propsFiles = Arrays
+ .stream(new File(edgePropsConfiguration.getEdgePropsDir())
+ .listFiles((d, name) -> propsFilePattern.matcher(name).matches()))
+ .collect(Collectors.toMap(new Function<File, String>() {
+ @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<String, DynamicJAXBContext> versionContextMap = new ConcurrentHashMap<>();
+ private static Map<String, HashMap<String, DynamicType>> xmlElementLookup = new ConcurrentHashMap<>();
+ private static Map<String, HashMap<String, VertexSchema>> 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<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors();
+ HashMap<String, DynamicType> types = new HashMap<String, DynamicType>();
+
+ 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<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors();
+ HashMap<String, VertexSchema> vertexMap = new HashMap<String, VertexSchema>();
+
+ 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<String> 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<String> versions = new ArrayList<String>();
+ for (String versionKey : versionContextMap.keySet()) {
+ Matcher matcher = versionPattern.matcher(versionKey);
+ if (matcher.find()) {
+ versions.add("V" + matcher.group(1));
+ }
+ }
+ return versions;
+ }
+
+ public static HashMap<String, DynamicType> getXmlLookupMap(String version) {
+ return xmlElementLookup.get(version);
+ }
+
+ public static HashMap<String, VertexSchema> 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<EdgeSchema> getAdjacentEdgeSchema(String vertexType, String version) throws SchemaProviderException {
+ RelationshipSchema relSchema = OxmEdgeRulesLoader.getSchemaForVersion(version);
+ Set<EdgeSchema> edges = new HashSet<EdgeSchema>();
+ List<EdgeRule> rules = relSchema.lookupAdjacentEdges(vertexType);
+
+ for (EdgeRule rule : rules) {
+ FromOxmEdgeSchema es = new FromOxmEdgeSchema();
+ es.fromEdgeRule(rule);
+ edges.add(es);
+ }
+
+ return edges;
+ }
+
+ @Override
+ public Set<EdgeSchema> getEdgeSchemaForSourceTarget(String sourceType, String targetType, String version) throws SchemaProviderException {
+ RelationshipSchema relSchema = OxmEdgeRulesLoader.getSchemaForVersion(version);
+ Set<EdgeSchema> edges = new HashSet<EdgeSchema>();
+ Set<String> 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<String, VertexSchema> 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<String, Map<String, Class<?>>> relations = new HashMap<>();
+ /**
+ * Hashmap of valid relationship types along with properties.
+ */
+ private Map<String, Map<String, Class<?>>> relationTypes = new HashMap<>();
+ private Map<String, EdgeRule> relationshipRules = new HashMap<>();
+
+ // A map storing the list of valid edge types for a source/target pair
+ private Map<String, Set<String>> edgeTypesForNodePair = new HashMap<>();
+
+
+ public RelationshipSchema(Multimap<String, EdgeRule> rules, String props) throws SchemaProviderException, IOException {
+ HashMap<String, String> 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<String> typeSet = new HashSet<String>();
+ 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<String, Class<?>> 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<EdgeRule> lookupAdjacentEdges(String vertex) throws SchemaProviderException {
+ List<EdgeRule> edges = new ArrayList<EdgeRule>();
+ for (EdgeRule rule : relationshipRules.values()) {
+ if (rule.getFrom().equals(vertex) || rule.getTo().equals(vertex)) {
+ edges.add(rule);
+ }
+ }
+
+ return edges;
+ }
+
+ public RelationshipSchema(List<String> jsonStrings) throws SchemaProviderException, IOException {
+ String edgeRules = jsonStrings.get(0);
+ String props = jsonStrings.get(1);
+
+ HashMap<String, ArrayList<LinkedHashMap<String, String>>> rules =
+ new ObjectMapper().readValue(edgeRules, HashMap.class);
+ HashMap<String, String> properties = new ObjectMapper().readValue(props, HashMap.class);
+ Map<String, Class<?>> 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<String, Class<?>> lookupRelation(String key) {
+ return this.relations.get(key);
+ }
+
+ public Map<String, Class<?>> 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<String> getValidRelationTypes(String source, String target) {
+ Set<String> typeList = edgeTypesForNodePair.get(buildNodePairKey(source, target));
+
+ if (typeList == null) {
+ return new HashSet<String>();
+ }
+
+ 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");
+ }
+ }
+}
+
+