2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
23 package org.onap.aai.audit;
25 import com.google.common.base.CaseFormat;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.LinkedHashSet;
31 import java.util.List;
34 import java.util.regex.Matcher;
35 import java.util.regex.Pattern;
37 import org.apache.commons.lang3.StringUtils;
38 import org.onap.aai.config.SpringContextAware;
39 import org.onap.aai.introspection.Introspector;
40 import org.onap.aai.introspection.Loader;
41 import org.onap.aai.introspection.LoaderFactory;
42 import org.onap.aai.introspection.ModelType;
43 import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
44 import org.onap.aai.logging.LogFormatTools;
45 import org.onap.aai.setup.SchemaVersion;
46 import org.onap.aai.setup.SchemaVersions;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49 import org.springframework.beans.BeansException;
50 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
53 * The Class ListEndpoints.
55 public class ListEndpoints {
57 private static final Logger LOGGER = LoggerFactory.getLogger(ListEndpoints.class);
59 private static final String START = "inventory";
60 private static final String[] blacklist = {"search", "aai-internal"};
62 private List<String> endpoints = new ArrayList<>();
63 private Map<String, String> endpointToLogicalName = new HashMap<>();
68 * @param args the arguments
70 public static void main(String[] args) {
72 try (AnnotationConfigApplicationContext context =
73 new AnnotationConfigApplicationContext("org.onap.aai.config", "org.onap.aai.setup")) {
74 String schemaUriBasePath = context.getEnvironment().getProperty("schema.uri.base.path");
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);
82 SchemaVersions schemaVersions = context.getBean(SchemaVersions.class);
83 ListEndpoints endPoints = new ListEndpoints(schemaUriBasePath, schemaVersions.getDefaultVersion());
85 LOGGER.info(endPoints.toString("relationship-list"));
86 } catch (BeansException e) {
87 LOGGER.warn("Unable to initialize AnnotationConfigApplicationContext ", LogFormatTools.getStackTop(e));
92 * Instantiates a new list endpoints.
94 * @param version the version
96 public ListEndpoints(String basePath, SchemaVersion version) {
98 Loader loader = SpringContextAware.getBean(LoaderFactory.class).createLoaderForVersion(ModelType.MOXY, version);
101 final Introspector start = loader.introspectorFromName(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 " + START + ", cannot run ListEndpoints audit");
115 private void beginAudit(Introspector obj, String uri, Set<String> visited) {
117 String currentUri = "";
119 if (!obj.getDbName().equals(START)) {
120 currentUri = uri + obj.getGenericURI();
124 if (obj.getName().equals("relationship-data") || obj.getName().equals("related-to-property")) {
127 if (!obj.isContainer()) {
128 endpoints.add(currentUri);
131 populateLogicalName(obj, uri, currentUri);
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)) {
139 endpoints.add(currentUri + obj.getLoader().introspectorFromName(key).getGenericURI());
140 } catch (AAIUnknownObjectException e) {
142 "Skipping endpoint for " + key + " (Unknown object) " + LogFormatTools.getStackTop(e));
148 outer: for (String propName : props) {
150 for (String item : blacklist) {
151 if (propName.equals(item)) {
155 if (obj.isListType(propName)) {
156 if (obj.isComplexGenericType(propName)) {
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));
168 } else if (obj.isComplexType(propName)) {
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));
185 * Populate logical name.
189 * @param currentUri the current uri
191 private void populateLogicalName(Introspector obj, String uri, String currentUri) {
193 if (obj.getDbName().equals("inventory") || currentUri.split("/").length <= 4
194 || currentUri.endsWith("relationship-list")) {
198 if (uri.endsWith("/relationship-list")) {
199 uri = uri.substring(0, uri.lastIndexOf('/'));
202 String logicalName = "";
205 if (!obj.getAllKeys().isEmpty()) {
207 Pattern p = Pattern.compile("/\\{[\\w\\d\\-]+\\}/\\{[\\w\\d\\-]+\\}+$");
208 Matcher m = p.matcher(currentUri);
211 keys = StringUtils.join(obj.getAllKeys(), "-and-");
213 keys = StringUtils.join(obj.getAllKeys(), "-or-");
215 keys = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, keys);
216 if (!keys.isEmpty()) {
217 keys = "With" + keys;
221 logicalName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, obj.getDbName()) + keys;
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('/')));
229 endpointToLogicalName.put(currentUri, logicalName);
234 * Gets the logical names.
236 * @return the logical names
238 public Map<String, String> getLogicalNames() {
240 return endpointToLogicalName;
245 * Gets the endpoints.
247 * @return the endpoints
249 public List<String> getEndpoints() {
251 return this.getEndpoints("");
256 * Gets the endpoints.
258 * @param filterOut the filter out
259 * @return the endpoints
261 public List<String> getEndpoints(String filterOut) {
262 List<String> result = new ArrayList<>();
265 if (!filterOut.equals("")) {
266 p = Pattern.compile(filterOut);
268 for (String s : endpoints) {
287 public String toString() {
288 StringBuilder sb = new StringBuilder();
289 for (String s : endpoints) {
292 return sb.toString();
299 * @param filterOut the filter out
302 public String toString(String filterOut) {
303 StringBuilder sb = new StringBuilder();
304 Pattern p = Pattern.compile(filterOut);
306 for (String s : endpoints) {
312 return sb.toString();