Apply multiplicity Rule upon Edge creation
[aai/gizmo.git] / src / main / java / org / onap / schema / RelationshipSchema.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017-2018 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 package org.onap.schema;
22
23
24 import java.io.IOException;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.stream.Collectors;
28 import javax.ws.rs.core.Response.Status;
29 import org.codehaus.jackson.map.ObjectMapper;
30 import org.onap.aai.edges.EdgeRule;
31 import org.onap.crud.exception.CrudException;
32 import com.google.common.collect.Multimap;
33
34
35 public class RelationshipSchema {
36
37   public static final String SCHEMA_SOURCE_NODE_TYPE = "from";
38   public static final String SCHEMA_TARGET_NODE_TYPE = "to";
39   public static final String SCHEMA_RELATIONSHIP_TYPE = "label";
40   public static final String SCHEMA_MULTIPLICITY_TYPE = "multiplicity";
41   public static final String SCHEMA_RULES_ARRAY = "rules";
42
43   private Map<String, Map<String, Class<?>>> relations = new HashMap<>();
44   /**
45    * Hashmap of valid relationship types along with properties.
46    */
47   private Map<String, Map<String, Class<?>>> relationTypes  = new HashMap<>();
48
49   private Map<String, EdgeRule> relationshipRules = new HashMap<>();
50
51   @SuppressWarnings("unchecked")
52   public RelationshipSchema(Multimap<String, EdgeRule> rules, String props) throws CrudException, IOException {
53     HashMap<String, String> properties = new ObjectMapper().readValue(props, HashMap.class);
54
55     // hold the true values of the edge rules by key - convert to java 8
56     for (EdgeRule rule : rules.values()) {
57       String key = buildRelation(rule.getFrom(), rule.getTo(), rule.getLabel());
58       relationshipRules.put(key, rule);
59     }
60
61     Map<String, Class<?>> edgeProps = properties.entrySet().stream().collect(Collectors.toMap(p -> p.getKey(), p -> {
62       try {
63         return resolveClass(p.getValue());
64       } catch (CrudException | ClassNotFoundException e) {
65         e.printStackTrace();
66       }
67       return null;
68     }));
69
70     rules.entries ().forEach ( (kv) -> {
71       relationTypes.put(kv.getValue ().getLabel (), edgeProps);
72       relations.put (buildRelation ( kv.getValue ().getFrom (), kv.getValue ().getTo (), kv.getValue ().getLabel ()), edgeProps);
73     });
74   }
75
76   public Map<String, Class<?>> lookupRelation(String key) {
77     return this.relations.get(key);
78   }
79
80   /**
81    * Extract the multiplicity type from the Edge rules
82    *
83    * @param key
84    * @return
85    * @throws CrudException
86    */
87   public String lookupRelationMultiplicity(String key) throws CrudException {
88     EdgeRule edgeRule = relationshipRules.get(key);
89
90     if (edgeRule == null) {
91       throw new CrudException("Invalid source/target/relationship type: " + key, Status.BAD_REQUEST);
92     }
93
94     if (edgeRule.getMultiplicityRule() != null) {
95       return edgeRule.getMultiplicityRule().toString();
96     }
97
98     return null;
99   }
100
101   public Map<String, Class<?>> lookupRelationType(String type) {
102     return this.relationTypes.get(type);
103   }
104
105   public boolean isValidType(String type) {
106     return relationTypes.containsKey(type);
107   }
108
109
110   private String buildRelation(String source, String target, String relation) {
111     return source + ":" + target + ":" + relation;
112   }
113
114   private Class<?> resolveClass(String type) throws CrudException, ClassNotFoundException {
115     Class<?> clazz = Class.forName(type);
116     validateClassTypes(clazz);
117     return clazz;
118   }
119
120   private void validateClassTypes(Class<?> clazz) throws CrudException {
121     if (!clazz.isAssignableFrom(Integer.class) && !clazz.isAssignableFrom(Double.class)
122             && !clazz.isAssignableFrom(Boolean.class) && !clazz.isAssignableFrom(String.class)) {
123       throw new CrudException("", Status.BAD_REQUEST);
124     }
125   }
126 }