Update eclipse.persistence and eelf.core in aai-common
[aai/aai-common.git] / aai-schema-abstraction / src / main / java / org / onap / aai / schemaif / oxm / OxmEdgeRulesLoader.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 package org.onap.aai.schemaif.oxm;
22
23 import com.google.common.collect.Multimap;
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.util.Arrays;
29 import java.util.Map;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.util.function.Function;
32 import java.util.regex.Matcher;
33 import java.util.regex.Pattern;
34 import java.util.stream.Collectors;
35 import org.apache.commons.io.IOUtils;
36 import org.onap.aai.cl.eelf.LoggerFactory;
37 import org.onap.aai.edges.EdgeIngestor;
38 import org.onap.aai.edges.EdgeRule;
39 import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
40 import org.onap.aai.schemaif.SchemaProviderException;
41 import org.onap.aai.schemaif.SchemaProviderMsgs;
42 import org.onap.aai.setup.SchemaVersion;
43 import org.onap.aai.setup.Translator;
44 import org.springframework.beans.factory.annotation.Autowired;
45 import org.springframework.stereotype.Component;
46
47 @Component
48 public class OxmEdgeRulesLoader {
49
50     private static Translator translator;
51     private static EdgeIngestor edgeIngestor;
52
53     private static EdgePropsConfiguration edgePropsConfiguration;
54
55     private static Map<String, RelationshipSchema> versionContextMap = new ConcurrentHashMap<>();
56
57     static final Pattern versionPattern = Pattern.compile("(?i)v(\\d*)");
58     static final String propsPrefix = "edge_properties_";
59     static final String propsSuffix = ".json";
60     final static Pattern propsFilePattern = Pattern.compile(propsPrefix + "(.*)" + propsSuffix);
61     final static Pattern propsVersionPattern = Pattern.compile("(?i)v\\d*");
62
63     private static org.onap.aai.cl.api.Logger logger =
64             LoggerFactory.getInstance().getLogger(OxmEdgeRulesLoader.class.getName());
65
66     private OxmEdgeRulesLoader() {}
67
68     /**
69      * This constructor presents an awkward marrying of Spring bean creation and static method use. This
70      * is technical debt that will need fixing.
71      *
72      * @param translator contains schema versions configuration
73      * @param edgeIngestor provides edge rules
74      * @param edgePropsConfiguration edge property validation configuration
75      */
76     @Autowired
77     public OxmEdgeRulesLoader(Translator translator, EdgeIngestor edgeIngestor,
78             EdgePropsConfiguration edgePropsConfiguration) {
79         OxmEdgeRulesLoader.translator = translator;
80         OxmEdgeRulesLoader.edgeIngestor = edgeIngestor;
81         OxmEdgeRulesLoader.edgePropsConfiguration = edgePropsConfiguration;
82     }
83
84     /**
85      * Finds all DB Edge Rules and Edge Properties files for all OXM models.
86      *
87      * @throws SchemaProviderException
88      * @throws SchemaProviderException 
89      */
90     public static synchronized void loadModels() throws SchemaProviderException {
91         Map<String, File> propFiles = edgePropertyFiles(edgePropsConfiguration);
92
93         if (logger.isDebugEnabled()) {
94             logger.debug("Loading DB Edge Rules");
95         }
96
97         for (String version : OxmSchemaLoader.getLoadedOXMVersions()) {
98             try {
99                 SchemaVersion schemaVersion = translator.getSchemaVersions().getVersions().stream()
100                         .filter(s -> s.toString().equalsIgnoreCase(version)).findAny().orElse(null);
101                 loadModel(schemaVersion, edgeIngestor, propFiles);
102             } catch (IOException | EdgeRuleNotFoundException e) {
103                 throw new SchemaProviderException(e.getMessage(), e);
104             }
105         }
106     }
107
108     /**
109      * Loads DB Edge Rules and Edge Properties for a given version.
110      *
111      * @throws SchemaProviderException
112      */
113
114     public static synchronized void loadModels(String v) throws SchemaProviderException {
115         Map<String, File> propFiles = edgePropertyFiles(edgePropsConfiguration);
116
117         if (logger.isDebugEnabled()) {
118             logger.debug("Loading DB Edge Rules ");
119         }
120
121         try {
122             SchemaVersion schemaVersion = translator.getSchemaVersions().getVersions().stream()
123                     .filter(s -> s.toString().equalsIgnoreCase(v)).findAny().orElse(null);
124
125             loadModel(schemaVersion, edgeIngestor, propFiles);
126         } catch (IOException | EdgeRuleNotFoundException e) {
127             throw new SchemaProviderException(e.getMessage());
128         }
129     }
130
131     /**
132      * Retrieves the DB Edge Rule relationship schema for a given version.
133      *
134      * @param version - The OXM version that we want the DB Edge Rule for.
135      * @return - A RelationshipSchema of the DB Edge Rule for the OXM version.
136      * @throws SchemaProviderException
137      */
138     public static RelationshipSchema getSchemaForVersion(String version) throws SchemaProviderException {
139
140         // If we haven't already loaded in the available OXM models, then do so now.
141         if (versionContextMap == null || versionContextMap.isEmpty()) {
142             loadModels();
143         } else if (!versionContextMap.containsKey(version)) {
144             logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "Error loading DB Edge Rules for: " + version);
145             throw new SchemaProviderException("Error loading DB Edge Rules for: " + version);
146         }
147
148         return versionContextMap.get(version);
149     }
150
151     /**
152      * Retrieves the DB Edge Rule relationship schema for all loaded OXM versions.
153      *
154      * @return - A Map of the OXM version and it's corresponding RelationshipSchema of the DB Edge Rule.
155      * @throws SchemaProviderException
156      */
157     public static Map<String, RelationshipSchema> getSchemas() throws SchemaProviderException {
158
159         // If we haven't already loaded in the available OXM models, then do so now.
160         if (versionContextMap == null || versionContextMap.isEmpty()) {
161             loadModels();
162         }
163         return versionContextMap;
164     }
165
166     /**
167      * Returns the latest available DB Edge Rule version.
168      *
169      * @return - A Map of the OXM version and it's corresponding RelationshipSchema of the DB Edge Rule.
170      * @throws SchemaProviderException
171      */
172     public static String getLatestSchemaVersion() throws SchemaProviderException {
173
174         // If we haven't already loaded in the available OXM models, then do so now.
175         if (versionContextMap == null || versionContextMap.isEmpty()) {
176             loadModels();
177         }
178
179         // If there are still no models available, then there's not much we can do...
180         if (versionContextMap.isEmpty()) {
181             logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "No available DB Edge Rules to get latest version for.");
182             throw new SchemaProviderException("No available DB Edge Rules to get latest version for.");
183         }
184
185         // Iterate over the available model versions to determine which is the most
186         // recent.
187         Integer latestVersion = null;
188         String latestVersionStr = null;
189         for (String versionKey : versionContextMap.keySet()) {
190
191             Matcher matcher = versionPattern.matcher(versionKey);
192             if (matcher.find()) {
193
194                 int currentVersion = Integer.parseInt(matcher.group(1));
195
196                 if ((latestVersion == null) || (currentVersion > latestVersion)) {
197                     latestVersion = currentVersion;
198                     latestVersionStr = versionKey;
199                 }
200             }
201         }
202
203         return latestVersionStr;
204     }
205
206     /**
207      * Reset the loaded DB Edge Rule schemas
208      *
209      */
210     public static void resetSchemaVersionContext() {
211         versionContextMap = new ConcurrentHashMap<>();
212     }
213
214     private static synchronized void loadModel(SchemaVersion version, EdgeIngestor edgeIngestor,
215             Map<String, File> props) throws IOException, SchemaProviderException, EdgeRuleNotFoundException {
216
217         Multimap<String, EdgeRule> edges = edgeIngestor.getAllRules(version);
218         String edgeProps;
219         if (props.get(version.toString().toLowerCase()) != null) {
220             edgeProps = IOUtils.toString(new FileInputStream(props.get(version.toString().toLowerCase())), "UTF-8");
221         } else {
222             throw new FileNotFoundException("The Edge Properties file for OXM version " + version + "was not found.");
223         }
224         if (edges != null) {
225             RelationshipSchema rs = new RelationshipSchema(edges, edgeProps);
226             versionContextMap.put(version.toString().toLowerCase(), rs);
227             logger.info(SchemaProviderMsgs.LOADED_DB_RULE_FILE, version.toString());
228         }
229     }
230
231     private static Map<String, File> edgePropertyFiles(EdgePropsConfiguration edgePropsConfiguration)
232             throws SchemaProviderException {
233         Map<String, File> propsFiles = Arrays
234                 .stream(new File(edgePropsConfiguration.getEdgePropsDir())
235                         .listFiles((d, name) -> propsFilePattern.matcher(name).matches()))
236                 .collect(Collectors.toMap(new Function<File, String>() {
237                     @Override
238                     public String apply(File f) {
239                         Matcher m1 = propsVersionPattern.matcher(f.getName());
240                         m1.find();
241                         return m1.group(0);
242                     }
243                 }, f -> f));
244         return propsFiles;
245     }
246 }