aboutsummaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/openecomp/schema/RelationshipSchema.java108
-rw-r--r--src/main/java/org/openecomp/schema/RelationshipSchemaLoader.java243
-rw-r--r--src/main/java/org/openecomp/schema/RelationshipSchemaValidator.java12
3 files changed, 209 insertions, 154 deletions
diff --git a/src/main/java/org/openecomp/schema/RelationshipSchema.java b/src/main/java/org/openecomp/schema/RelationshipSchema.java
index 5b28e28..a8d101d 100644
--- a/src/main/java/org/openecomp/schema/RelationshipSchema.java
+++ b/src/main/java/org/openecomp/schema/RelationshipSchema.java
@@ -25,95 +25,60 @@ package org.openecomp.schema;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
+import org.codehaus.jackson.map.ObjectMapper;
import org.openecomp.crud.exception.CrudException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
import javax.ws.rs.core.Response.Status;
+
public class RelationshipSchema {
private static final Gson gson = new GsonBuilder().create();
- public static final String SCHEMA_SOURCE_NODE_TYPE = "source-node-type";
- public static final String SCHEMA_TARGET_NODE_TYPE = "target-node-type";
- public static final String SCHEMA_RELATIONSHIP_TYPE = "relationship-type";
- public static final String SCHEMA_RELATIONSHIP_TYPES_ARRAY = "relationship-types";
- public static final String SCHEMA_RELATIONSHIP_PROPERTIES = "properties";
- public static final String SCHEMA_RELATIONS_ARRAY = "relations";
+ 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 Map<String, Map<String, Class<?>>> relations = new HashMap<>();
/**
- * key = source-node-type:target-node-type:relationship-type value = map of properties with name
- * and type . Like propertyName:PropertyType
- */
- private HashMap<String, HashMap<String, Class<?>>> relations
- = new HashMap<String, HashMap<String, Class<?>>>();
- /**
- * Hashmap of valid relationship types alongwith properrties.
+ * Hashmap of valid relationship types along with properties.
*/
- private HashMap<String, HashMap<String, Class<?>>> relationTypes
- = new HashMap<String, HashMap<String, Class<?>>>();
-
-
- public RelationshipSchema(String json) throws CrudException {
+ private Map<String, Map<String, Class<?>>> relationTypes = new HashMap<>();
- JsonParser parser = new JsonParser();
- try {
- JsonObject root = parser.parse(json).getAsJsonObject();
- JsonArray relationshipTypesArray = root.getAsJsonArray(SCHEMA_RELATIONSHIP_TYPES_ARRAY);
- JsonArray relationsArray = root.getAsJsonArray(SCHEMA_RELATIONS_ARRAY);
- //First load all the relationship-types
- for (JsonElement item : relationshipTypesArray) {
- JsonObject obj = item.getAsJsonObject();
- String type = obj.get(SCHEMA_RELATIONSHIP_TYPE).getAsString();
-
-
- HashMap<String, Class<?>> props = new HashMap<String, Class<?>>();
- Set<Map.Entry<String, JsonElement>> entries = obj.get(SCHEMA_RELATIONSHIP_PROPERTIES)
- .getAsJsonObject().entrySet();
-
- for (Map.Entry<String, JsonElement> entry : entries) {
- props.put(entry.getKey(), resolveClass(entry.getValue().getAsString()));
-
- }
- relationTypes.put(type, props);
+ public RelationshipSchema(List<String> jsonStrings) throws CrudException, 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 (CrudException | ClassNotFoundException e) {
+ e.printStackTrace();
}
+ return null;
+ }));
- for (JsonElement item : relationsArray) {
- JsonObject obj = item.getAsJsonObject();
- // Parse the Source/Taget nodeTypes
-
- String relationType = obj.get(SCHEMA_RELATIONSHIP_TYPE).getAsString();
- String key = obj.get(SCHEMA_SOURCE_NODE_TYPE).getAsString() + ":"
- + obj.get(SCHEMA_TARGET_NODE_TYPE).getAsString() + ":" + relationType;
-
-
- if (!relationTypes.containsKey(relationType)) {
- throw new CrudException(SCHEMA_RELATIONSHIP_TYPE + ": " + relationType + " not found",
- Status.BAD_REQUEST);
- }
-
- relations.put(key, relationTypes.get(relationType));
- }
- } catch (Exception e) {
- throw new CrudException(e.getMessage(), Status.BAD_REQUEST);
- }
-
+ 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 HashMap<String, Class<?>> lookupRelation(String key) {
+
+ public Map<String, Class<?>> lookupRelation(String key) {
return this.relations.get(key);
}
- public HashMap<String, Class<?>> lookupRelationType(String type) {
+ public Map<String, Class<?>> lookupRelationType(String type) {
return this.relationTypes.get(type);
}
@@ -121,6 +86,11 @@ public class RelationshipSchema {
return relationTypes.containsKey(type);
}
+
+ private String buildRelation(String source, String target, String relation){
+ return source + ":" + target + ":" + relation;
+ }
+
private Class<?> resolveClass(String type) throws CrudException, ClassNotFoundException {
Class<?> clazz = Class.forName(type);
validateClassTypes(clazz);
@@ -129,10 +99,10 @@ public class RelationshipSchema {
private void validateClassTypes(Class<?> clazz) throws CrudException {
if (!clazz.isAssignableFrom(Integer.class) && !clazz.isAssignableFrom(Double.class)
- && !clazz.isAssignableFrom(Boolean.class) && !clazz.isAssignableFrom(String.class)) {
+ && !clazz.isAssignableFrom(Boolean.class) && !clazz.isAssignableFrom(String.class)) {
throw new CrudException("", Status.BAD_REQUEST);
}
}
+}
-}
diff --git a/src/main/java/org/openecomp/schema/RelationshipSchemaLoader.java b/src/main/java/org/openecomp/schema/RelationshipSchemaLoader.java
index 51b33d0..7b68b35 100644
--- a/src/main/java/org/openecomp/schema/RelationshipSchemaLoader.java
+++ b/src/main/java/org/openecomp/schema/RelationshipSchemaLoader.java
@@ -24,135 +24,220 @@
package org.openecomp.schema;
import org.apache.commons.io.IOUtils;
+import org.openecomp.aai.dbmodel.DbEdgeRules;
import org.openecomp.cl.eelf.LoggerFactory;
import org.openecomp.crud.exception.CrudException;
import org.openecomp.crud.logging.CrudServiceMsgs;
import org.openecomp.crud.util.CrudServiceConstants;
import org.openecomp.crud.util.FileWatcher;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
+import org.springframework.core.io.UrlResource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+
+import java.io.*;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.Date;
-import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.SortedSet;
+import java.util.stream.Collectors;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import javax.ws.rs.core.Response.Status;
-import javax.xml.bind.JAXBException;
-
public class RelationshipSchemaLoader {
- private static Map<String, RelationshipSchema> versionContextMap
- = new ConcurrentHashMap<String, RelationshipSchema>();
+ private static Map<String, RelationshipSchema> versionContextMap = new ConcurrentHashMap<>();
private static SortedSet<Integer> versions = new TreeSet<Integer>();
private static Map<String, Timer> timers = new ConcurrentHashMap<String, Timer>();
-
- final static Pattern filePattern = Pattern.compile("aai_relationship_(.*).json");
+ final static String edgePropsFiles = "edge_properties_";
+ final static String fileExt = ".json";
+ final static Pattern rulesFilePattern = Pattern.compile("DbEdgeRules(.*)" + fileExt);
+ final static Pattern propsFilePattern = Pattern.compile(edgePropsFiles + "(.*)" + fileExt);
+ final static Pattern versionPattern = Pattern.compile(".*(v\\d+)" + fileExt);
private static org.openecomp.cl.api.Logger logger = LoggerFactory.getInstance()
- .getLogger(RelationshipSchemaLoader.class.getName());
+ .getLogger(RelationshipSchemaLoader.class.getName());
- public synchronized static void loadModels() {
+ public synchronized static void loadModels() throws CrudException {
+ load(rulesFilePattern, propsFilePattern);
+ }
- File[] listOfFiles = new File(CrudServiceConstants.CRD_HOME_MODEL).listFiles();
+ public synchronized static void loadModels(String version) throws CrudException {
+ String pattern = String.format(".*(%s)" + fileExt, version);
+ load(Pattern.compile(pattern), Pattern.compile(edgePropsFiles + version + fileExt));
+ }
- if (listOfFiles != null) {
- for (File file : listOfFiles) {
- if (file.isFile()) {
- Matcher matcher = filePattern.matcher(file.getName());
- if (matcher.matches()) {
- try {
- RelationshipSchemaLoader.loadModel(matcher.group(1), file);
- } catch (Exception e) {
- logger.error(CrudServiceMsgs.INVALID_OXM_FILE, file.getName(), e.getMessage());
- }
- }
+ public static RelationshipSchema getSchemaForVersion(String version) throws CrudException {
+ if (versionContextMap == null || versionContextMap.isEmpty()) {
+ loadModels();
+ } else if (!versionContextMap.containsKey(version)) {
+ try {
+ loadModels(version);
+ } catch (Exception e) {
+ throw new CrudException("", Status.NOT_FOUND);
+ }
+ }
+ RelationshipSchema schema = versionContextMap.get(version);
+ if (schema == null) {
+ throw new CrudException("", Status.NOT_FOUND);
+ } else
+ return schema;
+ }
- }
+ public static String getLatestSchemaVersion() throws CrudException {
+ return "v" + versions.last();
+ }
+
+ public static Map<String, RelationshipSchema> getVersionContextMap() {
+ return versionContextMap;
+ }
+
+ public static void setVersionContextMap(Map<String, RelationshipSchema> versionContextMap) {
+ RelationshipSchemaLoader.versionContextMap = versionContextMap;
+ }
+
+ public static void resetVersionContextMap() {
+ RelationshipSchemaLoader.versionContextMap = new ConcurrentHashMap<>();
+ }
+
+
+ private static void load(Pattern rulesPattern, Pattern edgePropsPattern) throws CrudException {
+ ClassLoader cl = RelationshipSchemaLoader.class.getClassLoader();
+ ResourcePatternResolver rulesResolver = new PathMatchingResourcePatternResolver(cl);
+ List<Object> rulesFiles;
+ String rulesDir = CrudServiceConstants.CRD_HOME_MODEL;
+ try {
+
+ // getResources method returns objects of type "Resource"
+ // 1. We are getting all the objects from the classpath which has "DbEdgeRules" in the name.
+ // 2. We run them through a filter and return only the objects which match the supplied pattern "p"
+ // 3. We then collect the objects in a list. At this point we have a list of the kind of files we require.
+ rulesFiles = Arrays.stream(rulesResolver.getResources("classpath*:/dbedgerules/DbEdgeRules*" + fileExt))
+ .filter(r -> !myMatcher(rulesPattern, r.getFilename()).isEmpty())
+ .collect(Collectors.toList());
+
+ // This gets all the objects of type "File" from external directory (not on the classpath)
+ // 1. From an external directory (one not on the classpath) we get all the objects of type "File"
+ // 2. We only return the files whose names matched the supplied pattern "p2".
+ // 3. We then collect all the objects in a list and add the contents of this list
+ // to the previous collection (rulesFiles)
+ rulesFiles.addAll(Arrays.stream(new File(rulesDir).listFiles((d, name) ->
+ edgePropsPattern.matcher(name).matches())).collect(Collectors.toList()));
+
+ if (rulesFiles.isEmpty()) {
+ logger.error(CrudServiceMsgs.INVALID_OXM_DIR, rulesDir);
+ throw new FileNotFoundException("DbEdgeRules and edge_properties files were not found.");
+ }
+
+ // Sort and then group the files with their versions, convert them to the schema, and add them to versionContextMap
+ // 1. Sort the files. We need the DbEdgeRules files to be before the edgeProperties files.
+ // 2. Group the files with their versions. ie. v11 -> ["DbEdgeRule_v11.json", "edgeProperties_v11.json"].
+ // The "group method" returns a HashMap whose key is the version and the value is a list of objects.
+ // 3. Go through each version and map the files into one schema using the "jsonFilesLoader" method.
+ // Also update the "versionContextMap" with the version and it's schema.
+ rulesFiles.stream().sorted(Comparator.comparing(RelationshipSchemaLoader::filename))
+ .collect(Collectors.groupingBy(f -> myMatcher(versionPattern, filename(f))))
+ .forEach((version, resourceAndFile) -> versionContextMap.put(version, jsonFilesLoader(version, resourceAndFile)));
+
+ logger.info(CrudServiceMsgs.LOADED_OXM_FILE, "Relationship Schema and Properties files: " + rulesFiles.stream().map(f -> filename(f)).collect(Collectors.toList()));
+ } catch (IOException e) {
+ logger.error(CrudServiceMsgs.INVALID_OXM_DIR, rulesDir);
+ throw new CrudException("DbEdgeRules or edge_properties files were not found.", new FileNotFoundException());
+ }
+ }
+
+ private static String filename (Object k) throws ClassCastException {
+ if (k instanceof UrlResource){
+ return ((UrlResource) k).getFilename();
+ } else if (k instanceof File) {
+ return ((File) k).getName();
+ } else {
+ throw new ClassCastException();
+ }
+ }
+
+ private static RelationshipSchema jsonFilesLoader (String version, List<Object> files) {
+ List<String> fileContents = new ArrayList<>();
+ RelationshipSchema rsSchema = null;
+ if (files.size() == 2) {
+ for (Object file : files) {
+ fileContents.add(jsonToRelationSchema(version, file));
+ versions.add(Integer.parseInt(version.substring(1)));
}
+
+ try {
+ rsSchema = new RelationshipSchema(fileContents);
+ } catch (CrudException | IOException e) {
+ e.printStackTrace();
+ logger.error(CrudServiceMsgs.INVALID_OXM_FILE,
+ files.stream().map(f -> filename(f)).collect(Collectors.toList()).toString(), e.getMessage());
+ }
+ return rsSchema;
} else {
- logger.error(CrudServiceMsgs.INVALID_OXM_DIR, CrudServiceConstants.CRD_HOME_MODEL);
+ logger.debug(CrudServiceMsgs.INVALID_OXM_FILE, "Expecting a rules file and a properties file but found: " +
+ files.stream().map(f-> filename(f)).collect(Collectors.toList()).toString());
}
+ return rsSchema;
+ }
+ private synchronized static void updateVersionContext(String version, RelationshipSchema rs){
+ versionContextMap.put(version, rs);
+ }
+ private synchronized static String jsonToRelationSchema (String version, Object file) {
+ InputStream inputStream = null;
+ String content = null;
+
+ try {
+ if (file instanceof UrlResource) {
+ inputStream = ((UrlResource) file).getInputStream();
+ } else {
+ inputStream = new FileInputStream((File) file);
+ addtimer(version, file);
+ }
+ content = IOUtils.toString(inputStream, "UTF-8");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return content;
}
- private static void addtimer(String version, File file) {
+ private static void addtimer(String version, Object file) {
TimerTask task = null;
task = new FileWatcher(
- file) {
+ (File) file) {
protected void onChange(File file) {
// here we implement the onChange
logger.info(CrudServiceMsgs.OXM_FILE_CHANGED, file.getName());
try {
- RelationshipSchemaLoader.loadModel(version, file);
+ // Cannot use the file object here because we also have to get the edge properties associated with that version.
+ // The properties are stored in a different file.
+ RelationshipSchemaLoader.loadModels(version);
} catch (Exception e) {
e.printStackTrace();
}
-
}
};
if (!timers.containsKey(version)) {
- Timer timer = new Timer("aai_relationship_" + version);
+ Timer timer = new Timer("db_edge_rules_" + version);
timer.schedule(task, new Date(), 10000);
timers.put(version, timer);
}
}
- private synchronized static void loadModel(String version, File file)
- throws JAXBException, IOException, CrudException {
-
- InputStream inputStream = new FileInputStream(file);
- String content = IOUtils.toString(inputStream, "UTF-8");
- versionContextMap.put(version, new RelationshipSchema(content));
- addtimer(version, file);
- versions.add(Integer.parseInt(version.substring(1)));
+ private static String myMatcher (Pattern p, String s) {
+ Matcher m = p.matcher(s);
+ return m.matches() ? m.group(1) : "";
}
-
- public static RelationshipSchema getSchemaForVersion(String version) throws CrudException {
- if (versionContextMap == null || versionContextMap.isEmpty()) {
- loadModels();
- } else if (!versionContextMap.containsKey(version)) {
- try {
- loadModel(version, new File(CrudServiceConstants.CRD_HOME_MODEL + "aai_relationship_"
- + version + ".json"));
- } catch (Exception e) {
- throw new CrudException("", Status.NOT_FOUND);
- }
- }
-
- return versionContextMap.get(version);
- }
-
- public static String getLatestSchemaVersion() throws CrudException {
- return "v" + versions.last();
- }
-
- public static Map<String, RelationshipSchema> getVersionContextMap() {
- return versionContextMap;
- }
-
- public static void setVersionContextMap(HashMap<String, RelationshipSchema> versionContextMap) {
- RelationshipSchemaLoader.versionContextMap = versionContextMap;
- }
-
- public static void main(String[] args) throws FileNotFoundException, Exception {
- File initialFile = new File("C:\\Software\\gizmo\\src\\main\\java\\org\\openecomp\\schema\\vio.json");
-
- loadModel("v8", initialFile);
- }
-
}
diff --git a/src/main/java/org/openecomp/schema/RelationshipSchemaValidator.java b/src/main/java/org/openecomp/schema/RelationshipSchemaValidator.java
index 552b60a..af20699 100644
--- a/src/main/java/org/openecomp/schema/RelationshipSchemaValidator.java
+++ b/src/main/java/org/openecomp/schema/RelationshipSchemaValidator.java
@@ -56,7 +56,7 @@ public class RelationshipSchemaValidator {
throw new CrudException("", Status.NOT_FOUND);
}
- HashMap<String, Class<?>> props = schema.lookupRelationType(type);
+ Map<String, Class<?>> props = schema.lookupRelationType(type);
Map<String, Object> result = new HashMap<String, Object>();
for (String key : filter.keySet()) {
@@ -128,7 +128,7 @@ public class RelationshipSchemaValidator {
String key = sourceNodeType + ":" + targetNodeType + ":" + type;
// find the validate the key from the schema
- HashMap<String, Class<?>> schemaObject = schema.lookupRelation(key);
+ Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
if (schemaObject == null) {
throw new CrudException("Invalid source/target/relationship type: " + key,
@@ -185,7 +185,7 @@ public class RelationshipSchemaValidator {
+ ":" + edge.getType();
// find the validate the key from the schema
- HashMap<String, Class<?>> schemaObject = schema.lookupRelation(key);
+ Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
if (schemaObject == null) {
Logger.warn("key :" + key
@@ -267,7 +267,7 @@ public class RelationshipSchemaValidator {
+ ":" + edge.getType();
// find the validate the key from the schema
- HashMap<String, Class<?>> schemaObject = schema.lookupRelation(key);
+ Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
if (schemaObject == null) {
Logger.warn("key :" + key
@@ -295,7 +295,7 @@ public class RelationshipSchemaValidator {
private static void validateEdgeProps(Edge.Builder builder, JsonElement props,
- HashMap<String, Class<?>> schemaObject)
+ Map<String, Class<?>> schemaObject)
throws CrudException {
Set<Map.Entry<String, JsonElement>> entries = props.getAsJsonObject().entrySet();
@@ -323,7 +323,7 @@ public class RelationshipSchemaValidator {
String key = edge.getSource().getType() + ":" + edge.getTarget().getType()
+ ":" + edge.getType();
- HashMap<String, Class<?>> schemaObject = schema.lookupRelation(key);
+ Map<String, Class<?>> schemaObject = schema.lookupRelation(key);
if (schemaObject == null || schemaObject.isEmpty()) {
return edge;