aed61e7a3ffae38817d4e45ab728ff8885eb7b7c
[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 com.att.eelf.configuration.EELFLogger;
26 import com.att.eelf.configuration.EELFManager;
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.db.props.AAIProperties;
42 import org.onap.aai.introspection.Introspector;
43 import org.onap.aai.introspection.Loader;
44 import org.onap.aai.introspection.LoaderFactory;
45 import org.onap.aai.introspection.ModelType;
46 import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
47 import org.onap.aai.logging.LogFormatTools;
48 import org.onap.aai.setup.SchemaVersion;
49 import org.onap.aai.setup.SchemaVersions;
50 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
51
52 /**
53  * The Class ListEndpoints.
54  */
55 public class ListEndpoints {
56
57     private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ListEndpoints.class);
58
59     private final String start = "inventory";
60     private final String[] blacklist = {"search", "aai-internal"};
61
62     private List<String> endpoints = new ArrayList<>();
63     private Map<String, String> endpointToLogicalName = new HashMap<String, String>();
64
65     /**
66      * The main method.
67      *
68      * @param args the arguments
69      */
70     public static void main(String[] args) {
71
72         AnnotationConfigApplicationContext context =
73                 new AnnotationConfigApplicationContext("org.onap.aai.config", "org.onap.aai.setup");
74
75         String schemaUriBasePath = context.getEnvironment().getProperty("schema.uri.base.path");
76
77         if (schemaUriBasePath == null) {
78             String errorMsg = "Unable to find the property schema.uri.base.path,"
79                     + " please check if specified in system property or in schema-ingest.properties";
80             System.err.println(errorMsg);
81             LOGGER.error(errorMsg);
82         }
83
84         SchemaVersions schemaVersions = context.getBean(SchemaVersions.class);
85         ListEndpoints endPoints = new ListEndpoints(schemaUriBasePath, schemaVersions.getDefaultVersion());
86
87         LOGGER.info(endPoints.toString("relationship-list"));
88     }
89
90     /**
91      * Instantiates a new list endpoints.
92      *
93      * @param version the version
94      */
95     public ListEndpoints(String basePath, SchemaVersion version) {
96
97         Loader loader = SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(ModelType.MOXY, version);
98
99         try {
100             final Introspector start = loader.introspectorFromName(this.start);
101             Set<String> startMap = new HashSet<>();
102             beginAudit(start, basePath + "/" + version, startMap);
103         } catch (AAIUnknownObjectException e) {
104             throw new RuntimeException("Failed to find object " + this.start + ", cannot run ListEndpoints audit");
105         }
106     }
107
108     /**
109      * Begin audit.
110      *
111      * @param obj the obj
112      * @param uri the uri
113      */
114     private void beginAudit(Introspector obj, String uri, Set<String> visited) {
115
116         String currentUri = "";
117
118         if (!obj.getDbName().equals("inventory")) {
119             currentUri = uri + obj.getGenericURI();
120         } else {
121             currentUri = uri;
122         }
123         if (obj.getName().equals("relationship-data") || obj.getName().equals("related-to-property")) {
124             return;
125         }
126         if (!obj.isContainer()) {
127             endpoints.add(currentUri);
128         }
129
130         String dbName = obj.getDbName();
131
132         populateLogicalName(obj, uri, currentUri);
133
134         Set<String> properties = obj.getProperties();
135         Set<String> props = new LinkedHashSet<>(properties);
136         if (obj.isContainer()) {
137             for (String key : visited) {
138                 if (props.remove(key)) {
139                     try {
140                         endpoints.add(currentUri + obj.getLoader().introspectorFromName(key).getGenericURI());
141                     } catch (AAIUnknownObjectException e) {
142                         LOGGER.warn(
143                                 "Skipping endpoint for " + key + " (Unknown object) " + LogFormatTools.getStackTop(e));
144                     }
145                 }
146             }
147         }
148
149         outer: for (String propName : props) {
150
151             for (String item : blacklist) {
152                 if (propName.equals(item)) {
153                     continue outer;
154                 }
155             }
156             if (obj.isListType(propName)) {
157                 if (obj.isComplexGenericType(propName)) {
158                     try {
159                         final Introspector nestedObj = obj.newIntrospectorInstanceOfNestedProperty(propName);
160                         Set<String> newVisited = new HashSet<>();
161                         newVisited.addAll(visited);
162                         newVisited.add(nestedObj.getDbName());
163                         beginAudit(nestedObj, currentUri, newVisited);
164                     } catch (AAIUnknownObjectException e) {
165                         LOGGER.warn("Skipping nested endpoint for " + propName + " (Unknown Object) "
166                                 + LogFormatTools.getStackTop(e));
167                     }
168                 }
169             } else if (obj.isComplexType(propName)) {
170                 try {
171                     final Introspector nestedObj = obj.newIntrospectorInstanceOfProperty(propName);
172                     Set<String> newVisited = new HashSet<>();
173                     newVisited.addAll(visited);
174                     newVisited.add(nestedObj.getDbName());
175                     beginAudit(nestedObj, currentUri, visited);
176                 } catch (AAIUnknownObjectException e) {
177                     LOGGER.warn("Skipping nested enpoint for " + propName + " (Unknown Object) "
178                             + LogFormatTools.getStackTop(e));
179                 }
180             }
181         }
182
183     }
184
185     /**
186      * Populate logical name.
187      *
188      * @param obj the obj
189      * @param uri the uri
190      * @param currentUri the current uri
191      */
192     private void populateLogicalName(Introspector obj, String uri, String currentUri) {
193
194         if (obj.getDbName().equals("inventory") || currentUri.split("/").length <= 4
195                 || currentUri.endsWith("relationship-list")) {
196             return;
197         }
198
199         if (uri.endsWith("/relationship-list")) {
200             uri = uri.substring(0, uri.lastIndexOf("/"));
201         }
202
203         String logicalName = "";
204         String keys = "";
205
206         if (!obj.getAllKeys().isEmpty()) {
207
208             Pattern p = Pattern.compile("/\\{[\\w\\d\\-]+\\}/\\{[\\w\\d\\-]+\\}+$");
209             Matcher m = p.matcher(currentUri);
210
211             if (m.find()) {
212                 keys = StringUtils.join(obj.getAllKeys(), "-and-");
213             } else {
214                 keys = StringUtils.join(obj.getAllKeys(), "-or-");
215             }
216             keys = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, keys);
217             if (!keys.isEmpty()) {
218                 keys = "With" + keys;
219             }
220         }
221
222         logicalName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, obj.getDbName()) + keys;
223
224         if (endpointToLogicalName.containsKey(uri) && uri.endsWith("}")) {
225             logicalName = logicalName + "From" + endpointToLogicalName.get(uri);
226         } else if (endpointToLogicalName.containsKey(uri.substring(0, uri.lastIndexOf("/")))) {
227             logicalName = logicalName + "From" + endpointToLogicalName.get(uri.substring(0, uri.lastIndexOf("/")));
228         }
229
230         endpointToLogicalName.put(currentUri, logicalName);
231
232     }
233
234     /**
235      * Gets the logical names.
236      *
237      * @return the logical names
238      */
239     public Map<String, String> getLogicalNames() {
240
241         return endpointToLogicalName;
242
243     }
244
245     /**
246      * Gets the endpoints.
247      *
248      * @return the endpoints
249      */
250     public List<String> getEndpoints() {
251
252         return this.getEndpoints("");
253
254     }
255
256     /**
257      * Gets the endpoints.
258      *
259      * @param filterOut the filter out
260      * @return the endpoints
261      */
262     public List<String> getEndpoints(String filterOut) {
263         List<String> result = new ArrayList<>();
264         Pattern p = null;
265         Matcher m = null;
266         if (!filterOut.equals("")) {
267             p = Pattern.compile(filterOut);
268             m = null;
269         }
270         for (String s : endpoints) {
271             if (p != null) {
272                 m = p.matcher(s);
273                 if (m.find()) {
274                     continue;
275                 }
276             }
277
278             result.add(s);
279         }
280
281         return result;
282
283     }
284
285     /**
286      * {@inheritDoc}
287      */
288     @Override
289     public String toString() {
290         StringBuilder sb = new StringBuilder();
291         for (String s : endpoints) {
292             sb.append(s + "\n");
293         }
294         return sb.toString();
295
296     }
297
298     /**
299      * To string.
300      *
301      * @param filterOut the filter out
302      * @return the string
303      */
304     public String toString(String filterOut) {
305         StringBuilder sb = new StringBuilder();
306         Pattern p = Pattern.compile(filterOut);
307         Matcher m = null;
308         for (String s : endpoints) {
309             m = p.matcher(s);
310             if (!m.find()) {
311                 sb.append(s + "\n");
312             }
313         }
314         return sb.toString();
315     }
316
317 }