2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.aai.introspection.tools;
23 import java.util.ArrayList;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Optional;
29 import org.openecomp.aai.db.props.AAIProperties;
30 import org.openecomp.aai.exceptions.AAIException;
31 import org.openecomp.aai.introspection.Introspector;
32 import org.openecomp.aai.introspection.IntrospectorWalker;
33 import org.openecomp.aai.introspection.Visibility;
34 import org.openecomp.aai.introspection.Wanderer;
35 import org.openecomp.aai.schema.enums.PropertyMetadata;
37 public class IntrospectorValidator implements Wanderer {
40 private List<Issue> issues = null;
41 private List<IssueResolver> issueResolvers = null;
42 private boolean validateRequired = true;
43 private final int maximumDepth;
44 private int currentDepth = 0;
46 private final Set<String> relationshipChain;
48 * Instantiates a new introspector validator.
50 * @param builder the builder
52 private IntrospectorValidator(IntrospectorValidator.Builder builder) {
53 this.validateRequired = builder.getValidateRequired();
54 this.issueResolvers = builder.getResolvers();
55 this.maximumDepth = builder.getMaximumDepth();
56 issues = new ArrayList<>();
58 relationshipChain = new HashSet<>();
60 relationshipChain.add("relationship-list");
61 relationshipChain.add("relationship");
62 relationshipChain.add("relationship-data");
63 relationshipChain.add("related-to-property");
72 * @return true, if successful
73 * @throws AAIException
75 public boolean validate(Introspector obj) throws AAIException {
76 IntrospectorWalker walker = new IntrospectorWalker(this);
77 this.currentDepth = 0;
80 for (Issue m : issues) {
81 if (!m.getSeverity().equals(Severity.WARNING)) {
94 public List<Issue> getIssues() {
99 * Sets the issue resolvers.
101 * @param resolvers the new issue resolvers
103 public void setIssueResolvers(List<IssueResolver> resolvers) {
104 issueResolvers = new ArrayList<>();
105 for (IssueResolver resolver : resolvers) {
106 issueResolvers.add(resolver);
113 * @return true, if successful
115 public boolean resolveIssues() {
116 boolean result = true;
117 for (Issue issue : issues) {
118 for (IssueResolver resolver : issueResolvers) {
119 if (resolver.resolveIssue(issue)) {
120 issue.setResolved(true);
123 if (!issue.isResolved()) {
135 public void processComplexObj(Introspector obj) {
137 if (this.currentDepth > this.maximumDepth && !relationshipChain.contains(obj.getDbName())) {
139 this.buildMessage(Severity.CRITICAL, IssueType.EXCEEDED_ALLOWED_DEPTH, "Maximum allowed depth of this object has been exceeded on: " + obj.getDbName());
140 message.setIntrospector(obj);
143 Set<String> requiredProps = obj.getRequiredProperties();
144 Set<String> keys = obj.getKeys();
145 Set<String> props = obj.getProperties();
147 for (String prop : props) {
148 Object value = obj.getValue(prop);
149 if (keys.contains(prop)) {
152 this.buildMessage(Severity.CRITICAL, IssueType.MISSING_KEY_PROP, "Missing key property: " + prop);
153 message.setIntrospector(obj);
154 message.setPropName(prop);
157 } else if (requiredProps.contains(prop)) {
158 if (value == null && validateRequired) {
160 this.buildMessage(Severity.CRITICAL, IssueType.MISSING_REQUIRED_PROP, "Missing required property: " + prop);
161 message.setIntrospector(obj);
162 message.setPropName(prop);
167 final Optional<String> visibility = obj.getPropertyMetadata(prop, PropertyMetadata.VISIBILITY);
168 if(visibility.isPresent() && Visibility.internal.equals(Visibility.valueOf(visibility.get()))) {
170 this.buildMessage(Severity.ERROR, IssueType.PROPERTY_NOT_VISIBLE, "client attemptted to set property not visible: " + prop);
171 message.setIntrospector(obj);
172 message.setPropName(prop);
178 if (!relationshipChain.contains(obj.getDbName())) {
188 public void processPrimitive(String propName, Introspector obj) {
196 public void processPrimitiveList(String propName, Introspector obj) {
204 public void modifyComplexList(List<Introspector> list, List<Object> listReference, Introspector parent, Introspector child) {
210 * Builds the message.
212 * @param severity the severity
213 * @param error the error
214 * @param detail the detail
217 private Issue buildMessage(Severity severity, IssueType error, String detail) {
218 Issue message = new Issue();
219 message.setSeverity(severity);
220 message.setType(error);
221 message.setDetail(detail);
230 public boolean createComplexObjIfNull() {
238 public int createComplexListSize(Introspector parent, Introspector child) {
242 public static class Builder {
244 private boolean validateRequired = true;
245 private List<IssueResolver> issueResolvers = null;
246 private int maximumDepth = AAIProperties.MAXIMUM_DEPTH;
248 * Instantiates a new builder.
250 * @param llBuilder the ll builder
253 issueResolvers = new ArrayList<IssueResolver>();
259 * @param validateRequired the validate required
260 * @return the builder
262 public Builder validateRequired(boolean validateRequired) {
263 this.validateRequired = validateRequired;
267 public Builder restrictDepth(int depth) {
268 this.maximumDepth = depth;
274 * @param resolver the resolver
275 * @return the builder
277 public Builder addResolver(IssueResolver resolver) {
278 issueResolvers.add(resolver);
285 * @return the introspector validator
287 public IntrospectorValidator build() {
288 return new IntrospectorValidator(this);
292 * Gets the validate required.
294 * @return the validate required
296 public boolean getValidateRequired() {
297 return this.validateRequired;
301 * Gets the resolvers.
303 * @return the resolvers
305 public List<IssueResolver> getResolvers() {
306 return this.issueResolvers;
309 public int getMaximumDepth() {
310 return this.maximumDepth;