Skip to content

Commit 15c9e3e

Browse files
committed
Add warning message for unknown parameters
LMCROSSITXSADEPLOY-3137
1 parent 64bfdb8 commit 15c9e3e

20 files changed

+869
-4
lines changed

multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/model/Resource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ public Resource setRequiredDependencies(List<RequiredDependency> requiredDepende
194194
@Override
195195
public void accept(ElementContext context, Visitor visitor) {
196196
visitor.visit(context, this);
197-
if (majorSchemaVersion > 3) {
197+
if (majorSchemaVersion > 2) {
198198
for (RequiredDependency requiredDependency : requiredDependencies) {
199199
visitor.visit(new ElementContext(this, context), requiredDependency);
200200
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.cloudfoundry.multiapps.mta.resolvers;
2+
3+
import java.util.List;
4+
5+
public class CustomParameterContainer {
6+
7+
private final String parameterOwner;
8+
private final List<String> customParameters;
9+
10+
private final String prefixedName;
11+
12+
public CustomParameterContainer(String parameterOwner, List<String> parameters, String prefixedName) {
13+
this.parameterOwner = parameterOwner;
14+
this.customParameters = parameters;
15+
this.prefixedName = prefixedName;
16+
}
17+
18+
public String getParameterOwner() {
19+
return parameterOwner;
20+
}
21+
22+
public String getPrefixedName() {
23+
return prefixedName;
24+
}
25+
26+
public List<String> getParameters() {
27+
return customParameters;
28+
}
29+
30+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package org.cloudfoundry.multiapps.mta.resolvers;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Objects;
6+
import java.util.Set;
7+
import java.util.stream.Collectors;
8+
9+
import org.cloudfoundry.multiapps.mta.helpers.SimplePropertyVisitor;
10+
import org.cloudfoundry.multiapps.mta.helpers.VisitableObject;
11+
import org.cloudfoundry.multiapps.mta.model.DeploymentDescriptor;
12+
import org.cloudfoundry.multiapps.mta.model.ElementContext;
13+
import org.cloudfoundry.multiapps.mta.model.Hook;
14+
import org.cloudfoundry.multiapps.mta.model.Module;
15+
import org.cloudfoundry.multiapps.mta.model.ParametersContainer;
16+
import org.cloudfoundry.multiapps.mta.model.ProvidedDependency;
17+
import org.cloudfoundry.multiapps.mta.model.RequiredDependency;
18+
import org.cloudfoundry.multiapps.mta.model.Resource;
19+
import org.cloudfoundry.multiapps.mta.model.Visitor;
20+
21+
public abstract class ParameterChecker extends Visitor implements SimplePropertyVisitor {
22+
private List<CustomParameterContainer> unsupportedParameters;
23+
24+
private Set<String> predefinedParametersForContainer;
25+
26+
protected abstract Set<String> getModuleParametersToMatch();
27+
28+
protected abstract Set<String> getModuleHookParametersToMatch();
29+
30+
protected abstract Set<String> getResourceParametersToMatch();
31+
32+
protected abstract Set<String> getGlobalParametersToMatch();
33+
34+
protected abstract Set<String> getDependencyParametersToMatch();
35+
36+
public List<CustomParameterContainer> getCustomParameters(DeploymentDescriptor descriptor) {
37+
this.unsupportedParameters = new ArrayList<>();
38+
descriptor.accept(this);
39+
return this.unsupportedParameters;
40+
}
41+
42+
@Override
43+
public void visit(ElementContext context, DeploymentDescriptor descriptor) {
44+
matchAndStore(null, getGlobalParametersToMatch(), descriptor, null);
45+
}
46+
47+
@Override
48+
public void visit(ElementContext context, Module module) {
49+
matchAndStore(module.getName(), getModuleParametersToMatch(), module, context.getPrefixedName());
50+
}
51+
52+
@Override
53+
public void visit(ElementContext context, ProvidedDependency providedDependency) {
54+
matchAndStore(providedDependency.getName(), getDependencyParametersToMatch(), providedDependency, context.getPrefixedName());
55+
}
56+
57+
@Override
58+
public void visit(ElementContext context, RequiredDependency requiredDependency) {
59+
matchAndStore(requiredDependency.getName(), getDependencyParametersToMatch(), requiredDependency, context.getPrefixedName());
60+
}
61+
62+
@Override
63+
public void visit(ElementContext context, Resource resource) {
64+
matchAndStore(resource.getName(), getResourceParametersToMatch(), resource, context.getPrefixedName());
65+
}
66+
67+
@Override
68+
public void visit(ElementContext context, Hook hook) {
69+
matchAndStore(hook.getName(), getModuleHookParametersToMatch(), hook, context.getPrefixedName());
70+
}
71+
72+
private void matchAndStore(String name, Set<String> parametersToMatch, ParametersContainer parametersContainer, String prefixedName) {
73+
this.predefinedParametersForContainer = parametersToMatch;
74+
List<String> unmatched = findMatchesInParameters(parametersContainer);
75+
if (!unmatched.isEmpty()) {
76+
unsupportedParameters.add(new CustomParameterContainer(name, unmatched, prefixedName));
77+
}
78+
}
79+
80+
private List<String> findMatchesInParameters(ParametersContainer parametersContainer) {
81+
List<String> matchedKeys = (List<String>) findMatchesInKeySet(parametersContainer.getParameters()
82+
.keySet());
83+
return matchedKeys.stream()
84+
.filter(Objects::nonNull)
85+
.collect(Collectors.toList());
86+
}
87+
88+
private Object findMatchesInKeySet(Set<String> keys) {
89+
return new VisitableObject(keys).accept(this);
90+
}
91+
92+
@Override
93+
public Object visit(String key, String value) {
94+
return parameterKeyMatches(value);
95+
}
96+
97+
private String parameterKeyMatches(String valueToMatch) {
98+
if (predefinedParametersForContainer != null && !predefinedParametersForContainer.contains(valueToMatch)) {
99+
return valueToMatch;
100+
}
101+
return null;
102+
}
103+
104+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.cloudfoundry.multiapps.mta.resolvers;
2+
3+
import java.util.List;
4+
5+
public class ReferenceContainer {
6+
7+
private final String referenceOwner;
8+
private final List<Reference> references;
9+
10+
public ReferenceContainer(String referenceOwner, List<Reference> references) {
11+
this.referenceOwner = referenceOwner;
12+
this.references = references;
13+
}
14+
15+
public String getReferenceOwner() {
16+
return referenceOwner;
17+
}
18+
19+
public List<Reference> getReferences() {
20+
return references;
21+
}
22+
23+
}

multiapps-mta/src/main/java/org/cloudfoundry/multiapps/mta/resolvers/ReferencePattern.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88
public enum ReferencePattern implements ValueMatcher {
99

1010
PLACEHOLDER("(?<!\\\\)\\$\\{(.+?)\\}", "${%s}"), SHORT("(?<!\\\\)~\\{(.+?)\\}", "~{%s}"), FULLY_QUALIFIED("(?<!\\\\)~\\{(.+?)/(.+?)\\}",
11-
"~{%s/%s}");
11+
"~{%s/%s}");
1212

1313
private String pattern;
1414
private String patternFormat;
1515

16+
private final Pattern compiledPattern;
17+
1618
ReferencePattern(String pattern, String patternFormat) {
1719
this.pattern = pattern;
1820
this.patternFormat = patternFormat;
21+
this.compiledPattern = Pattern.compile(pattern);
1922
}
2023

2124
protected boolean hasPropertySetSegment() {
@@ -28,8 +31,7 @@ protected boolean hasDepthOfReference() {
2831

2932
@Override
3033
public List<Reference> match(String line) {
31-
Matcher matcher = Pattern.compile(this.pattern)
32-
.matcher(line);
34+
Matcher matcher = this.compiledPattern.matcher(line);
3335
List<Reference> references = new ArrayList<>();
3436
while (matcher.find()) {
3537
String matchedValue = matcher.group(0);
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package org.cloudfoundry.multiapps.mta.resolvers;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.Collections;
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.Objects;
9+
import java.util.stream.Collectors;
10+
11+
import org.cloudfoundry.multiapps.mta.helpers.SimplePropertyVisitor;
12+
import org.cloudfoundry.multiapps.mta.helpers.VisitableObject;
13+
import org.cloudfoundry.multiapps.mta.model.DeploymentDescriptor;
14+
import org.cloudfoundry.multiapps.mta.model.ElementContext;
15+
import org.cloudfoundry.multiapps.mta.model.Hook;
16+
import org.cloudfoundry.multiapps.mta.model.Module;
17+
import org.cloudfoundry.multiapps.mta.model.ProvidedDependency;
18+
import org.cloudfoundry.multiapps.mta.model.RequiredDependency;
19+
import org.cloudfoundry.multiapps.mta.model.Resource;
20+
import org.cloudfoundry.multiapps.mta.model.Visitor;
21+
22+
public class ReferencesFinder extends Visitor implements SimplePropertyVisitor {
23+
24+
private List<ReferenceContainer> foundReferences;
25+
26+
public List<ReferenceContainer> getAllReferences(DeploymentDescriptor descriptor) {
27+
this.foundReferences = new ArrayList<>();
28+
descriptor.accept(this);
29+
return this.foundReferences;
30+
}
31+
32+
@Override
33+
public void visit(ElementContext context, DeploymentDescriptor descriptor) {
34+
collectReferences(null, descriptor.getParameters());
35+
}
36+
37+
@Override
38+
public void visit(ElementContext context, Module module) {
39+
collectReferences(module.getName(), module.getParameters(), module.getProperties());
40+
}
41+
42+
@Override
43+
public void visit(ElementContext context, ProvidedDependency providedDependency) {
44+
collectReferences(context.getPrefixedName(), providedDependency.getParameters(), providedDependency.getProperties());
45+
}
46+
47+
@Override
48+
public void visit(ElementContext context, RequiredDependency requiredDependency) {
49+
collectReferences(context.getPrefixedName(), requiredDependency.getParameters(), requiredDependency.getProperties());
50+
}
51+
52+
@Override
53+
public void visit(ElementContext context, Resource resource) {
54+
collectReferences(resource.getName(), resource.getParameters(), resource.getProperties());
55+
}
56+
57+
@Override
58+
public void visit(ElementContext context, Hook hook) {
59+
collectReferences(context.getPrefixedName(), hook.getParameters());
60+
}
61+
62+
private void collectReferences(String name, Map<String, Object>... maps) {
63+
List<Reference> merged = Arrays.stream(maps)
64+
.flatMap(map -> findReferencesInParameters(map).stream())
65+
.collect(Collectors.toList());
66+
67+
if (!merged.isEmpty()) {
68+
foundReferences.add(new ReferenceContainer(name, merged));
69+
}
70+
}
71+
72+
private List<Reference> findReferencesInParameters(Map<String, Object> map) {
73+
if (map == null) {
74+
return Collections.emptyList();
75+
}
76+
77+
List<Reference> matchedKeys = (List<Reference>) findReferencesInList(new ArrayList(map.values()));
78+
return matchedKeys.stream()
79+
.filter(Objects::nonNull)
80+
.collect(Collectors.toList());
81+
}
82+
83+
private Object findReferencesInList(List<String> keys) {
84+
Object result = new VisitableObject(keys).accept(this);
85+
return extractReferences(result);
86+
}
87+
88+
private List<Reference> extractReferences(Object input) {
89+
if (input == null) {
90+
return Collections.emptyList();
91+
}
92+
93+
if (input instanceof Reference) {
94+
return List.of((Reference) input);
95+
}
96+
97+
if (input instanceof List<?>) {
98+
return ((List<?>) input).stream()
99+
.flatMap(item -> extractReferences(item).stream())
100+
.collect(Collectors.toList());
101+
}
102+
103+
if (input instanceof Map<?, ?>) {
104+
return ((Map<?, ?>) input).values()
105+
.stream()
106+
.flatMap(value -> extractReferences(value).stream())
107+
.collect(Collectors.toList());
108+
}
109+
110+
return Collections.emptyList();
111+
}
112+
113+
@Override
114+
public Object visit(String key, String value) {
115+
return referencePatternMatches(value);
116+
}
117+
118+
private List<Reference> referencePatternMatches(String valueToMatch) {
119+
//Not using ReferencePattern.values() in order to have the more specific FULLY_QUALIFIED pattern before SHORT
120+
for (ReferencePattern pattern : List.of(
121+
ReferencePattern.PLACEHOLDER,
122+
ReferencePattern.FULLY_QUALIFIED,
123+
ReferencePattern.SHORT)) {
124+
125+
List<Reference> references = pattern.match(valueToMatch);
126+
if (!references.isEmpty()) {
127+
return references;
128+
}
129+
}
130+
return null;
131+
}
132+
133+
}

0 commit comments

Comments
 (0)