Passed
Push — master ( e943e4...3e3b4a )
by Filip
02:50
created

isObject(JsonSchema)   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
dl 0
loc 2
rs 10
1
package com.hltech.vaunt.validator;
2
3
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
4
import com.fasterxml.jackson.module.jsonSchema.types.ObjectSchema;
5
import com.fasterxml.jackson.module.jsonSchema.types.SimpleTypeSchema;
6
import com.fasterxml.jackson.module.jsonSchema.types.StringSchema;
7
import com.hltech.vaunt.core.domain.model.Contract;
8
import com.hltech.vaunt.core.domain.model.DestinationType;
9
import com.hltech.vaunt.core.domain.model.Service;
10
11
import java.util.List;
12
import java.util.Map;
13
import java.util.Optional;
14
import java.util.Set;
15
import java.util.stream.Collectors;
16
17
public class VauntValidator {
18
19
    public List<ValidationResult> validate(Service consumer, Service provider) {
20
        return consumer.getExpectations().getProviderNameToContracts().get(provider.getName()).stream()
21
                .map(consumerContract -> validateWithMatchingProviderContract(
22
                        consumerContract, provider.getCapabilities().getContracts()))
23
                .collect(Collectors.toList());
24
    }
25
26
    public List<ValidationResult> validate(List<Contract> expectations, List<Contract> capabilities) {
27
        return expectations.stream()
28
                .map(consumerContract -> validateWithMatchingProviderContract(consumerContract, capabilities))
29
                .collect(Collectors.toList());
30
    }
31
32
    private ValidationResult validateWithMatchingProviderContract(
33
            Contract consumerContract, List<Contract> providerContracts) {
34
        List<Contract> contracts = providerContracts.stream()
35
                .filter(providerContract -> isEndpointMatching(consumerContract, providerContract))
36
                .collect(Collectors.toList());
37
38
        if (contracts.isEmpty()) {
39
            return ValidationResult.failure(consumerContract, ValidationError.MISSING_ENDPOINT);
40
        }
41
42
        Optional<Contract> matchingProviderContract = contracts.stream()
43
                .filter(providerContract -> isSchemaAndIdMatching(
44
                        consumerContract.getBody(), providerContract.getBody()))
45
                .findFirst();
46
47
        return matchingProviderContract
48
                .map(contract -> ValidationResult.success(consumerContract))
49
                .orElseGet(() -> ValidationResult.failure(consumerContract, contracts, ValidationError.WRONG_SCHEMA));
50
51
    }
52
53
    private boolean isEndpointMatching(Contract firstContract, Contract secondContract) {
54
        return isTmpQueueMatching(firstContract, secondContract)
55
                || (isDstTypeMatching(firstContract, secondContract)
56
                && isDstNameMatching(firstContract, secondContract));
57
    }
58
59
    private boolean isTmpQueueMatching(Contract firstContract, Contract secondContract) {
60
        return firstContract.getDestinationType() == DestinationType.TEMPORARY_QUEUE
61
                && isDstTypeMatching(firstContract, secondContract);
62
    }
63
64
    private boolean isDstTypeMatching(Contract firstContract, Contract secondContract) {
65
        return firstContract.getDestinationType() == secondContract.getDestinationType();
66
    }
67
68
    private boolean isDstNameMatching(Contract firstContract, Contract secondContract) {
69
        return firstContract.getDestinationName().equals(secondContract.getDestinationName());
70
    }
71
72
    private boolean isSchemaAndIdMatching(JsonSchema consumerBody, JsonSchema providerBody) {
73
        if (!consumerBody.getId().equals(providerBody.getId())) {
74
            return false;
75
        }
76
77
        return isSchemaMatching(consumerBody, providerBody);
78
    }
79
80
    private boolean isSchemaMatching(JsonSchema consumerBody, JsonSchema providerBody) {
81
        if (isEnum(consumerBody) && isEnum(providerBody)) {
82
            return compareEnumSchema(consumerBody, providerBody);
83
        }
84
85
        if (isObject(consumerBody) && isObject(providerBody)) {
86
            return compareObjectSchema(consumerBody.asObjectSchema(), providerBody.asObjectSchema());
87
        }
88
89
        return consumerBody.equals(providerBody);
90
    }
91
92
    private boolean isEnum(JsonSchema schema) {
93
        return schema.asStringSchema() != null && schema.asStringSchema().getEnums().size() > 0;
94
    }
95
96
    private boolean isObject(JsonSchema schema) {
97
        return schema.asObjectSchema() != null;
98
    }
99
100
    private boolean compareEnumSchema(JsonSchema consumerBody, JsonSchema providerBody) {
101
        return compareStringSchemaPart(consumerBody.asStringSchema(), providerBody.asStringSchema())
102
                && compareSimpleTypeSchemaPart(consumerBody.asSimpleTypeSchema(), providerBody.asSimpleTypeSchema())
103
                && compareJsonSchemaPart(consumerBody, providerBody);
104
    }
105
106
    private boolean compareStringSchemaPart(StringSchema consumerBody, StringSchema providerBody) {
107
        return equals(consumerBody.getMaxLength(), providerBody.getMaxLength())
108
                && equals(consumerBody.getMinLength(), providerBody.getMinLength())
109
                && equals(consumerBody.getPattern(), providerBody.getPattern())
110
                && equals(consumerBody.getFormat(), providerBody.getFormat())
111
                && compareEnum(consumerBody.getEnums(), providerBody.getEnums());
112
    }
113
114
    private boolean compareSimpleTypeSchemaPart(SimpleTypeSchema consumerBody, SimpleTypeSchema providerBody) {
115
        return equals(consumerBody.getDefault(), providerBody.getDefault())
116
                && equals(consumerBody.getTitle(), providerBody.getTitle())
117
                && equals(consumerBody.getPathStart(), providerBody.getPathStart())
118
                && equals(consumerBody.getLinks(), providerBody.getLinks());
119
    }
120
121
    private boolean compareJsonSchemaPart(JsonSchema consumerBody, JsonSchema providerBody) {
122
        return equals(consumerBody.getId(), providerBody.getId())
123
                && equals(consumerBody.getRequired(), providerBody.getRequired())
124
                && equals(consumerBody.getReadonly(), providerBody.getReadonly())
125
                && equals(consumerBody.get$ref(), providerBody.get$ref())
126
                && equals(consumerBody.get$schema(), providerBody.get$schema())
127
                && equals(consumerBody.getDisallow(), providerBody.getDisallow())
128
                && equals(consumerBody.getExtends(), providerBody.getExtends());
129
    }
130
131
    private boolean compareEnum(Set<String> consumerEnums, Set<String> providerEnums) {
132
        return providerEnums.containsAll(consumerEnums);
133
    }
134
135
    private boolean compareObjectSchema(ObjectSchema consumerBody, ObjectSchema providerBody) {
136
        return equals(consumerBody.getAdditionalProperties(), providerBody.getAdditionalProperties())
137
                && equals(consumerBody.getDependencies(), providerBody.getDependencies())
138
                && equals(consumerBody.getPatternProperties(), providerBody.getPatternProperties())
139
                && compareObjectProperties(consumerBody.getProperties(), providerBody.getProperties());
140
    }
141
142
    private boolean compareObjectProperties(
143
            Map<String, JsonSchema> consumerProperties, Map<String, JsonSchema> providerProperties) {
144
        return consumerProperties.keySet().equals(providerProperties.keySet())
145
                && consumerProperties.keySet().stream()
146
                    .allMatch(key -> isSchemaMatching(consumerProperties.get(key), providerProperties.get(key)));
147
    }
148
149
    private boolean equals(Object object1, Object object2) {
150
        if (object1 == null) {
151
            return object2 == null;
152
        } else {
153
            return object1.equals(object2);
154
        }
155
    }
156
}
157