Merge "[AAI] Fix doc config files"
[aai/aai-common.git] / aai-schema-abstraction / src / main / java / org / onap / aai / schemaif / oxm / RelationshipSchema.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2019 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *    http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23
24 package org.onap.aai.schemaif.oxm;
25
26 import com.google.common.collect.Multimap;
27
28 import java.io.IOException;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.LinkedHashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.stream.Collectors;
37
38 import org.codehaus.jackson.map.ObjectMapper;
39 import org.onap.aai.cl.eelf.LoggerFactory;
40 import org.onap.aai.edges.EdgeRule;
41 import org.onap.aai.schemaif.SchemaProviderException;
42 import org.onap.aai.schemaif.SchemaProviderMsgs;
43
44 public class RelationshipSchema {
45
46     public static final String SCHEMA_SOURCE_NODE_TYPE = "from";
47     public static final String SCHEMA_TARGET_NODE_TYPE = "to";
48     public static final String SCHEMA_RELATIONSHIP_TYPE = "label";
49     public static final String SCHEMA_RULES_ARRAY = "rules";
50
51     private static org.onap.aai.cl.api.Logger logger =
52             LoggerFactory.getInstance().getLogger(RelationshipSchema.class.getName());
53
54     private Map<String, Map<String, Class<?>>> relations = new HashMap<>();
55     /**
56      * Hashmap of valid relationship types along with properties.
57      */
58     private Map<String, Map<String, Class<?>>> relationTypes = new HashMap<>();
59     private Map<String, EdgeRule> relationshipRules = new HashMap<>();
60
61     // A map storing the list of valid edge types for a source/target pair
62     private Map<String, Set<String>> edgeTypesForNodePair = new HashMap<>();
63
64     public RelationshipSchema(Multimap<String, EdgeRule> rules, String props)
65             throws SchemaProviderException, IOException {
66         HashMap<String, String> properties = new ObjectMapper().readValue(props, HashMap.class);
67
68         // hold the true values of the edge rules by key
69         for (EdgeRule rule : rules.values()) {
70             String nodePairKey = buildNodePairKey(rule.getFrom(), rule.getTo());
71             if (edgeTypesForNodePair.get(nodePairKey) == null) {
72                 Set<String> typeSet = new HashSet<String>();
73                 typeSet.add(rule.getLabel());
74                 edgeTypesForNodePair.put(nodePairKey, typeSet);
75             } else {
76                 edgeTypesForNodePair.get(nodePairKey).add(rule.getLabel());
77             }
78
79             String key = buildRelation(rule.getFrom(), rule.getTo(), rule.getLabel());
80             relationshipRules.put(key, rule);
81         }
82
83         Map<String, Class<?>> edgeProps =
84                 properties.entrySet().stream().collect(Collectors.toMap(p -> p.getKey(), p -> {
85                     try {
86                         return resolveClass(p.getValue());
87                     } catch (SchemaProviderException | ClassNotFoundException e) {
88                         logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "Error in RelationshipSchema: " + e);
89                     }
90                     return null;
91                 }));
92
93         rules.entries().forEach((kv) -> {
94             relationTypes.put(kv.getValue().getLabel(), edgeProps);
95             relations.put(buildRelation(kv.getValue().getFrom(), kv.getValue().getTo(), kv.getValue().getLabel()),
96                     edgeProps);
97         });
98     }
99
100     public EdgeRule lookupEdgeRule(String key) throws SchemaProviderException {
101         return relationshipRules.get(key);
102     }
103
104     public List<EdgeRule> lookupAdjacentEdges(String vertex) throws SchemaProviderException {
105         List<EdgeRule> edges = new ArrayList<EdgeRule>();
106         for (EdgeRule rule : relationshipRules.values()) {
107             if (rule.getFrom().equals(vertex) || rule.getTo().equals(vertex)) {
108                 edges.add(rule);
109             }
110         }
111
112         return edges;
113     }
114
115     public RelationshipSchema(List<String> jsonStrings) throws SchemaProviderException, IOException {
116         String edgeRules = jsonStrings.get(0);
117         String props = jsonStrings.get(1);
118
119         HashMap<String, ArrayList<LinkedHashMap<String, String>>> rules =
120                 new ObjectMapper().readValue(edgeRules, HashMap.class);
121         HashMap<String, String> properties = new ObjectMapper().readValue(props, HashMap.class);
122         Map<String, Class<?>> edgeProps =
123                 properties.entrySet().stream().collect(Collectors.toMap(p -> p.getKey(), p -> {
124                     try {
125                         return resolveClass(p.getValue());
126                     } catch (SchemaProviderException | ClassNotFoundException e) {
127                         logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "Error in RelationshipSchema: " + e);
128                     }
129                     return null;
130                 }));
131
132         rules.get(SCHEMA_RULES_ARRAY).forEach(l -> {
133             relationTypes.put(l.get(SCHEMA_RELATIONSHIP_TYPE), edgeProps);
134             relations.put(buildRelation(l.get(SCHEMA_SOURCE_NODE_TYPE), l.get(SCHEMA_TARGET_NODE_TYPE),
135                     l.get(SCHEMA_RELATIONSHIP_TYPE)), edgeProps);
136         });
137     }
138
139     public Map<String, Class<?>> lookupRelation(String key) {
140         return this.relations.get(key);
141     }
142
143     public Map<String, Class<?>> lookupRelationType(String type) {
144         return this.relationTypes.get(type);
145     }
146
147     public boolean isValidType(String type) {
148         return relationTypes.containsKey(type);
149     }
150
151     private String buildRelation(String source, String target, String relation) {
152         return source + ":" + target + ":" + relation;
153     }
154
155     public Set<String> getValidRelationTypes(String source, String target) {
156         Set<String> typeList = edgeTypesForNodePair.get(buildNodePairKey(source, target));
157
158         if (typeList == null) {
159             return new HashSet<String>();
160         }
161
162         return typeList;
163     }
164
165     private String buildNodePairKey(String source, String target) {
166         return source + ":" + target;
167     }
168
169     private Class<?> resolveClass(String type) throws SchemaProviderException, ClassNotFoundException {
170         Class<?> clazz = Class.forName(type);
171         validateClassTypes(clazz);
172         return clazz;
173     }
174
175     private void validateClassTypes(Class<?> clazz) throws SchemaProviderException {
176         if (!clazz.isAssignableFrom(Integer.class) && !clazz.isAssignableFrom(Double.class)
177                 && !clazz.isAssignableFrom(Boolean.class) && !clazz.isAssignableFrom(String.class)) {
178             throw new SchemaProviderException("BAD_REQUEST");
179         }
180     }
181 }