AAI-common sonar fixes
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / audit / ListEndpoints.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  *
7  * Modifications Copyright (C) 2019 IBM.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *    http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.aai.audit;
24
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27 import com.google.common.base.CaseFormat;
28
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.LinkedHashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38
39 import org.apache.commons.lang.StringUtils;
40 import org.onap.aai.config.SpringContextAware;
41 import org.onap.aai.introspection.Introspector;
42 import org.onap.aai.introspection.Loader;
43 import org.onap.aai.introspection.LoaderFactory;
44 import org.onap.aai.introspection.ModelType;
45 import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
46 import org.onap.aai.logging.LogFormatTools;
47 import org.onap.aai.setup.SchemaVersion;
48 import org.onap.aai.setup.SchemaVersions;
49 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
50
51 /**
52  * The Class ListEndpoints.
53  */
54 public class ListEndpoints {
55
56     private static final Logger LOGGER = LoggerFactory.getLogger(ListEndpoints.class);
57
58     private static final String START = "inventory";
59     private static final String[] blacklist = {"search", "aai-internal"};
60
61     private List<String> endpoints = new ArrayList<>();
62     private Map<String, String> endpointToLogicalName = new HashMap<>();
63
64     /**
65      * The main method.
66      *
67      * @param args the arguments
68      */
69     public static void main(String[] args) {
70
71         AnnotationConfigApplicationContext context =
72                 new AnnotationConfigApplicationContext("org.onap.aai.config", "org.onap.aai.setup");
73
74         String schemaUriBasePath = context.getEnvironment().getProperty("schema.uri.base.path");
75
76         if (schemaUriBasePath == null) {
77             String errorMsg = "Unable to find the property schema.uri.base.path,"
78                     + " please check if specified in system property or in schema-ingest.properties";
79             LOGGER.error(errorMsg);
80         }
81
82         SchemaVersions schemaVersions = context.getBean(SchemaVersions.class);
83         ListEndpoints endPoints = new ListEndpoints(schemaUriBasePath, schemaVersions.getDefaultVersion());
84
85         LOGGER.info(endPoints.toString("relationship-list"));
86     }
87
88     /**
89      * Instantiates a new list endpoints.
90      *
91      * @param version the version
92      */
93     public ListEndpoints(String basePath, SchemaVersion version) {
94
95         Loader loader = SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(ModelType.MOXY, version);
96
97         try {
98             final Introspector start = loader.introspectorFromName(START);
99             Set<String> startMap = new HashSet<>();
100             beginAudit(start, basePath + "/" + version, startMap);
101         } catch (AAIUnknownObjectException e) {
102             throw new RuntimeException("Failed to find object " + START + ", cannot run ListEndpoints audit");
103         }
104     }
105
106     /**
107      * Begin audit.
108      *
109      * @param obj the obj
110      * @param uri the uri
111      */
112     private void beginAudit(Introspector obj, String uri, Set<String> visited) {
113
114         String currentUri = "";
115
116         if (!obj.getDbName().equals(START)) {
117             currentUri = uri + obj.getGenericURI();
118         } else {
119             currentUri = uri;
120         }
121         if (obj.getName().equals("relationship-data") || obj.getName().equals("related-to-property")) {
122             return;
123         }
124         if (!obj.isContainer()) {
125             endpoints.add(currentUri);
126         }
127
128         populateLogicalName(obj, uri, currentUri);
129
130         Set<String> properties = obj.getProperties();
131         Set<String> props = new LinkedHashSet<>(properties);
132         if (obj.isContainer()) {
133             for (String key : visited) {
134                 if (props.remove(key)) {
135                     try {
136                         endpoints.add(currentUri + obj.getLoader().introspectorFromName(key).getGenericURI());
137                     } catch (AAIUnknownObjectException e) {
138                         LOGGER.warn(
139                                 "Skipping endpoint for " + key + " (Unknown object) " + LogFormatTools.getStackTop(e));
140                     }
141                 }
142             }
143         }
144
145         outer: for (String propName : props) {
146
147             for (String item : blacklist) {
148                 if (propName.equals(item)) {
149                     continue outer;
150                 }
151             }
152             if (obj.isListType(propName)) {
153                 if (obj.isComplexGenericType(propName)) {
154                     try {
155                         final Introspector nestedObj = obj.newIntrospectorInstanceOfNestedProperty(propName);
156                         Set<String> newVisited = new HashSet<>();
157                         newVisited.addAll(visited);
158                         newVisited.add(nestedObj.getDbName());
159                         beginAudit(nestedObj, currentUri, newVisited);
160                     } catch (AAIUnknownObjectException e) {
161                         LOGGER.warn("Skipping nested endpoint for " + propName + " (Unknown Object) "
162                                 + LogFormatTools.getStackTop(e));
163                     }
164                 }
165             } else if (obj.isComplexType(propName)) {
166                 try {
167                     final Introspector nestedObj = obj.newIntrospectorInstanceOfProperty(propName);
168                     Set<String> newVisited = new HashSet<>();
169                     newVisited.addAll(visited);
170                     newVisited.add(nestedObj.getDbName());
171                     beginAudit(nestedObj, currentUri, visited);
172                 } catch (AAIUnknownObjectException e) {
173                     LOGGER.warn("Skipping nested enpoint for " + propName + " (Unknown Object) "
174                             + LogFormatTools.getStackTop(e));
175                 }
176             }
177         }
178
179     }
180
181     /**
182      * Populate logical name.
183      *
184      * @param obj the obj
185      * @param uri the uri
186      * @param currentUri the current uri
187      */
188     private void populateLogicalName(Introspector obj, String uri, String currentUri) {
189
190         if (obj.getDbName().equals("inventory") || currentUri.split("/").length <= 4
191                 || currentUri.endsWith("relationship-list")) {
192             return;
193         }
194
195         if (uri.endsWith("/relationship-list")) {
196             uri = uri.substring(0, uri.lastIndexOf('/'));
197         }
198
199         String logicalName = "";
200         String keys = "";
201
202         if (!obj.getAllKeys().isEmpty()) {
203
204             Pattern p = Pattern.compile("/\\{[\\w\\d\\-]+\\}/\\{[\\w\\d\\-]+\\}+$");
205             Matcher m = p.matcher(currentUri);
206
207             if (m.find()) {
208                 keys = StringUtils.join(obj.getAllKeys(), "-and-");
209             } else {
210                 keys = StringUtils.join(obj.getAllKeys(), "-or-");
211             }
212             keys = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, keys);
213             if (!keys.isEmpty()) {
214                 keys = "With" + keys;
215             }
216         }
217
218         logicalName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, obj.getDbName()) + keys;
219
220         if (endpointToLogicalName.containsKey(uri) && uri.endsWith("}")) {
221             logicalName = logicalName + "From" + endpointToLogicalName.get(uri);
222         } else if (endpointToLogicalName.containsKey(uri.substring(0, uri.lastIndexOf('/')))) {
223             logicalName = logicalName + "From" + endpointToLogicalName.get(uri.substring(0, uri.lastIndexOf('/')));
224         }
225
226         endpointToLogicalName.put(currentUri, logicalName);
227
228     }
229
230     /**
231      * Gets the logical names.
232      *
233      * @return the logical names
234      */
235     public Map<String, String> getLogicalNames() {
236
237         return endpointToLogicalName;
238
239     }
240
241     /**
242      * Gets the endpoints.
243      *
244      * @return the endpoints
245      */
246     public List<String> getEndpoints() {
247
248         return this.getEndpoints("");
249
250     }
251
252     /**
253      * Gets the endpoints.
254      *
255      * @param filterOut the filter out
256      * @return the endpoints
257      */
258     public List<String> getEndpoints(String filterOut) {
259         List<String> result = new ArrayList<>();
260         Pattern p = null;
261         Matcher m = null;
262         if (!filterOut.equals("")) {
263             p = Pattern.compile(filterOut);
264         }
265         for (String s : endpoints) {
266             if (p != null) {
267                 m = p.matcher(s);
268                 if (m.find()) {
269                     continue;
270                 }
271             }
272
273             result.add(s);
274         }
275
276         return result;
277
278     }
279
280     /**
281      * {@inheritDoc}
282      */
283     @Override
284     public String toString() {
285         StringBuilder sb = new StringBuilder();
286         for (String s : endpoints) {
287             sb.append(s + "\n");
288         }
289         return sb.toString();
290
291     }
292
293     /**
294      * To string.
295      *
296      * @param filterOut the filter out
297      * @return the string
298      */
299     public String toString(String filterOut) {
300         StringBuilder sb = new StringBuilder();
301         Pattern p = Pattern.compile(filterOut);
302         Matcher m = null;
303         for (String s : endpoints) {
304             m = p.matcher(s);
305             if (!m.find()) {
306                 sb.append(s + "\n");
307             }
308         }
309         return sb.toString();
310     }
311
312 }