/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. * Copyright © 2017-2018 Amdocs * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= */ package org.onap.schema; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import javax.ws.rs.core.Response.Status; import org.codehaus.jackson.map.ObjectMapper; import org.onap.aai.edges.EdgeRule; import org.onap.crud.exception.CrudException; 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_MULTIPLICITY_TYPE = "multiplicity"; public static final String SCHEMA_RULES_ARRAY = "rules"; private Map>> relations = new HashMap<>(); /** * Hashmap of valid relationship types along with properties. */ private Map>> relationTypes = new HashMap<>(); private Map relationshipRules = new HashMap<>(); // A map storing the list of valid edge types for a source/target pair private Map> edgeTypesForNodePair = new HashMap<>(); @SuppressWarnings("unchecked") public RelationshipSchema(Multimap rules, String props) throws CrudException, IOException { HashMap properties = new ObjectMapper().readValue(props, HashMap.class); // hold the true values of the edge rules by key - convert to java 8 for (EdgeRule rule : rules.values()) { String key = buildRelation(rule.getFrom(), rule.getTo(), rule.getLabel()); relationshipRules.put(key, rule); String nodePairKey = buildNodePairKey(rule.getFrom(), rule.getTo()); if (edgeTypesForNodePair.get(nodePairKey) == null) { Set typeSet = new HashSet(); typeSet.add(rule.getLabel()); edgeTypesForNodePair.put(nodePairKey, typeSet); } else { edgeTypesForNodePair.get(nodePairKey).add(rule.getLabel()); } } Map> edgeProps = properties.entrySet().stream().collect(Collectors.toMap(p -> p.getKey(), p -> { try { return resolveClass(p.getValue()); } catch (CrudException | ClassNotFoundException e) { e.printStackTrace(); } 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 Map> lookupRelation(String key) { return this.relations.get(key); } /** * Extract the multiplicity type from the Edge rules * * @param key * @return * @throws CrudException */ public String lookupRelationMultiplicity(String key) throws CrudException { EdgeRule edgeRule = relationshipRules.get(key); if (edgeRule == null) { throw new CrudException("Invalid source/target/relationship type: " + key, Status.BAD_REQUEST); } if (edgeRule.getMultiplicityRule() != null) { return edgeRule.getMultiplicityRule().toString(); } return null; } public Map> lookupRelationType(String type) { return this.relationTypes.get(type); } public boolean isValidType(String type) { return relationTypes.containsKey(type); } public Set getValidRelationTypes(String source, String target) { Set typeList = edgeTypesForNodePair.get(buildNodePairKey(source, target)); if (typeList == null) { return new HashSet(); } return typeList; } private String buildRelation(String source, String target, String relation) { return source + ":" + target + ":" + relation; } private String buildNodePairKey(String source, String target) { return source + ":" + target; } private Class resolveClass(String type) throws CrudException, ClassNotFoundException { Class clazz = Class.forName(type); validateClassTypes(clazz); return clazz; } private void validateClassTypes(Class clazz) throws CrudException { if (!clazz.isAssignableFrom(Integer.class) && !clazz.isAssignableFrom(Double.class) && !clazz.isAssignableFrom(Boolean.class) && !clazz.isAssignableFrom(String.class)) { throw new CrudException("", Status.BAD_REQUEST); } } }