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