diff options
Diffstat (limited to 'src/main/java/org/openecomp/schema/RelationshipSchemaLoader.java')
-rw-r--r-- | src/main/java/org/openecomp/schema/RelationshipSchemaLoader.java | 243 |
1 files changed, 164 insertions, 79 deletions
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); - } - } |