Passed
Push — master ( 725c83...770833 )
by Filip
03:36
created

com.hltech.vaunt.validator.VauntValidator   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 106
c 3
b 0
f 0
dl 0
loc 168
rs 9.52
wmc 36

23 Methods

Rating   Name   Duplication   Size   Complexity  
A validate(Service,Service) 0 5 1
A validate(List,List) 0 4 1
A isDstNameMatching(Contract,Contract) 0 2 1
A isIdMatching(JsonSchema,JsonSchema) 0 2 1
A isTmpQueueMatching(Contract,Contract) 0 3 1
A isEndpointMatching(Contract,Contract) 0 4 1
A isDstTypeMatching(Contract,Contract) 0 2 1
A isObjectSchema(JsonSchema) 0 2 1
A isRequired(JsonSchema) 0 2 1
A isStringSchema(JsonSchema) 0 2 1
A validateWithMatchingProviderContract(Contract,List) 0 25 5
A compareObjectSchema(ObjectSchema,ObjectSchema) 0 8 1
A compareJsonSchemaPart(JsonSchema,JsonSchema) 0 8 1
A compareSimpleTypeSchemaPart(SimpleTypeSchema,SimpleTypeSchema) 0 5 1
A representsString(StringSchema) 0 2 1
A compareObjectProperties(Map,Map) 0 6 1
A representsEnum(StringSchema) 0 2 1
A equals(Object,Object) 0 5 2
A compareContainerTypeSchemaPart(ContainerTypeSchema,ContainerTypeSchema) 0 3 1
A compareEnumSchema(JsonSchema,JsonSchema) 0 4 1
A compareEnum(StringSchema,StringSchema) 0 10 5
A compareStringSchemaPart(StringSchema,StringSchema) 0 6 1
A isContentMatching(JsonSchema,JsonSchema) 0 10 5
1
package com.hltech.vaunt.validator;
2
3
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
4
import com.fasterxml.jackson.module.jsonSchema.types.ContainerTypeSchema;
5
import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema;
6
import com.fasterxml.jackson.module.jsonSchema.types.SimpleTypeSchema;
7
import com.fasterxml.jackson.module.jsonSchema.types.StringSchema;
8
import com.hltech.vaunt.core.domain.model.Contract;
9
import com.hltech.vaunt.core.domain.model.DestinationType;
10
import com.hltech.vaunt.core.domain.model.Service;
11
12
import java.util.List;
13
import java.util.Map;
14
import java.util.stream.Collectors;
15
16
public class VauntValidator {
17
18
    public List<ValidationResult> validate(Service consumer, Service provider) {
19
        return consumer.getExpectations().getProviderNameToContracts().get(provider.getName()).stream()
20
                .map(consumerContract -> validateWithMatchingProviderContract(
21
                        consumerContract, provider.getCapabilities().getContracts()))
22
                .collect(Collectors.toList());
23
    }
24
25
    public List<ValidationResult> validate(List<Contract> expectations, List<Contract> capabilities) {
26
        return expectations.stream()
27
                .map(consumerContract -> validateWithMatchingProviderContract(consumerContract, capabilities))
28
                .collect(Collectors.toList());
29
    }
30
31
    private ValidationResult validateWithMatchingProviderContract(Contract consumerContract,
32
                                                                  List<Contract> providerContracts) {
33
        List<Contract> endpointMatchingContracts = providerContracts.stream()
34
                .filter(providerContract -> isEndpointMatching(consumerContract, providerContract))
35
                .collect(Collectors.toList());
36
37
        if (endpointMatchingContracts.isEmpty()) {
38
            return ValidationResult.failure(consumerContract, ValidationError.MISSING_ENDPOINT);
39
        }
40
41
        List<Contract> idMatchingContracts = endpointMatchingContracts.stream()
42
                .filter(providerContract -> isIdMatching(consumerContract.getBody(), providerContract.getBody()))
43
                .collect(Collectors.toList());
44
45
        if (idMatchingContracts.isEmpty()) {
46
            return ValidationResult.failure(consumerContract, ValidationError.MISSING_MESSAGE_WITH_NAME);
47
        }
48
49
        if (idMatchingContracts.size() > 1) {
50
            return ValidationResult.failure(consumerContract, ValidationError.DUPLICATE_MATCH);
51
        }
52
53
        return isContentMatching(consumerContract.getBody(),
54
                idMatchingContracts.get(0).getBody()) ? ValidationResult.success(consumerContract)
55
                : ValidationResult.failure(consumerContract, idMatchingContracts.get(0), ValidationError.WRONG_SCHEMA);
56
    }
57
58
    private boolean isEndpointMatching(Contract firstContract, Contract secondContract) {
59
        return isTmpQueueMatching(firstContract, secondContract)
60
                || (isDstTypeMatching(firstContract, secondContract)
61
                && isDstNameMatching(firstContract, secondContract));
62
    }
63
64
    private boolean isTmpQueueMatching(Contract firstContract, Contract secondContract) {
65
        return firstContract.getDestinationType() == DestinationType.TEMPORARY_QUEUE
66
                && isDstTypeMatching(firstContract, secondContract);
67
    }
68
69
    private boolean isDstTypeMatching(Contract firstContract, Contract secondContract) {
70
        return firstContract.getDestinationType() == secondContract.getDestinationType();
71
    }
72
73
    private boolean isDstNameMatching(Contract firstContract, Contract secondContract) {
74
        return firstContract.getDestinationName().equals(secondContract.getDestinationName());
75
    }
76
77
    private boolean isIdMatching(JsonSchema consumerBody, JsonSchema providerBody) {
78
        return consumerBody.getId().equals(providerBody.getId());
79
    }
80
81
    private boolean isContentMatching(JsonSchema consumerBody, JsonSchema providerBody) {
82
        if (isStringSchema(consumerBody) && isStringSchema(providerBody)) {
83
            return compareEnumSchema(consumerBody, providerBody);
84
        }
85
86
        if (isObjectSchema(consumerBody) && isObjectSchema(providerBody)) {
87
            return compareObjectSchema(consumerBody.asObjectSchema(), providerBody.asObjectSchema());
88
        }
89
90
        return consumerBody.equals(providerBody);
91
    }
92
93
    private boolean isRequired(JsonSchema schema) {
94
        return schema.getRequired() != null && schema.getRequired();
95
    }
96
97
    private boolean isObjectSchema(JsonSchema schema) {
98
        return schema.asObjectSchema() != null;
99
    }
100
101
    private boolean isStringSchema(JsonSchema schema) {
102
        return schema.asStringSchema() != null;
103
    }
104
105
    private boolean compareEnumSchema(JsonSchema consumerBody, JsonSchema providerBody) {
106
        return compareStringSchemaPart(consumerBody.asStringSchema(), providerBody.asStringSchema())
107
                && compareSimpleTypeSchemaPart(consumerBody.asSimpleTypeSchema(), providerBody.asSimpleTypeSchema())
108
                && compareJsonSchemaPart(consumerBody, providerBody);
109
    }
110
111
    private boolean compareStringSchemaPart(StringSchema consumerBody, StringSchema providerBody) {
112
        return equals(consumerBody.getMaxLength(), providerBody.getMaxLength())
113
                && equals(consumerBody.getMinLength(), providerBody.getMinLength())
114
                && equals(consumerBody.getPattern(), providerBody.getPattern())
115
                && equals(consumerBody.getFormat(), providerBody.getFormat())
116
                && compareEnum(consumerBody, providerBody);
117
    }
118
119
    private boolean compareSimpleTypeSchemaPart(SimpleTypeSchema consumerBody, SimpleTypeSchema providerBody) {
120
        return equals(consumerBody.getDefault(), providerBody.getDefault())
121
                && equals(consumerBody.getTitle(), providerBody.getTitle())
122
                && equals(consumerBody.getPathStart(), providerBody.getPathStart())
123
                && equals(consumerBody.getLinks(), providerBody.getLinks());
124
    }
125
126
    private boolean compareJsonSchemaPart(JsonSchema consumerBody, JsonSchema providerBody) {
127
        return equals(consumerBody.getId(), providerBody.getId())
128
                && !isRequired(consumerBody) || isRequired(providerBody)
129
                && equals(consumerBody.getReadonly(), providerBody.getReadonly())
130
                && equals(consumerBody.get$ref(), providerBody.get$ref())
131
                && equals(consumerBody.get$schema(), providerBody.get$schema())
132
                && equals(consumerBody.getDisallow(), providerBody.getDisallow())
133
                && equals(consumerBody.getExtends(), providerBody.getExtends());
134
    }
135
136
    private boolean compareContainerTypeSchemaPart(ContainerTypeSchema consumerBody, ContainerTypeSchema providerBody) {
137
        return equals(consumerBody.getEnums(), providerBody.getEnums())
138
                && equals(consumerBody.getOneOf(), providerBody.getOneOf());
139
    }
140
141
    private boolean compareEnum(StringSchema consumerBody, StringSchema providerBody) {
142
        if (representsString(consumerBody) && representsEnum(providerBody)) {
143
            return false;
144
        }
145
146
        if (representsEnum(consumerBody) && representsEnum(providerBody)) {
147
            return providerBody.getEnums().containsAll(consumerBody.getEnums());
148
        }
149
150
        return true;
151
    }
152
153
    private boolean representsEnum(StringSchema body) {
154
        return body.getEnums().size() > 0;
155
    }
156
157
    private boolean representsString(StringSchema body) {
158
        return body.getEnums().size() == 0;
159
    }
160
161
    private boolean compareObjectSchema(ObjectSchema consumerBody, ObjectSchema providerBody) {
162
        return equals(consumerBody.getAdditionalProperties(), providerBody.getAdditionalProperties())
163
                && equals(consumerBody.getDependencies(), providerBody.getDependencies())
164
                && equals(consumerBody.getPatternProperties(), providerBody.getPatternProperties())
165
                && compareContainerTypeSchemaPart(consumerBody, providerBody)
166
                && compareSimpleTypeSchemaPart(consumerBody, providerBody)
167
                && compareJsonSchemaPart(consumerBody, providerBody)
168
                && compareObjectProperties(consumerBody.getProperties(), providerBody.getProperties());
169
    }
170
171
    private boolean compareObjectProperties(Map<String, JsonSchema> consumerProperties,
172
                                            Map<String, JsonSchema> providerProperties) {
173
174
        return providerProperties.keySet().containsAll(consumerProperties.keySet())
175
                && consumerProperties.keySet().stream()
176
                .allMatch(key -> isContentMatching(consumerProperties.get(key), providerProperties.get(key)));
177
    }
178
179
    private boolean equals(Object object1, Object object2) {
180
        if (object1 == null) {
181
            return object2 == null;
182
        } else {
183
            return object1.equals(object2);
184
        }
185
    }
186
}
187