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