Passed
Push — master ( 4bedd1...f49baa )
by Tomasz
03:35
created

validateCapabilities(ServiceContracts,Collection)   A

Complexity

Conditions 1

Size

Total Lines 8
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
package dev.hltech.dredd.domain.validation;
2
3
import dev.hltech.dredd.domain.contracts.ServiceContracts;
4
import lombok.AccessLevel;
5
import lombok.AllArgsConstructor;
6
import lombok.Getter;
7
8
import java.util.Collection;
9
import java.util.List;
10
import java.util.Map;
11
import java.util.Optional;
12
import java.util.stream.Stream;
13
14
import static com.google.common.collect.Lists.newArrayList;
15
import static dev.hltech.dredd.domain.validation.InterfaceContractValidator.InteractionValidationStatus.FAILED;
16
import static dev.hltech.dredd.domain.validation.InterfaceContractValidator.InteractionValidationStatus.OK;
17
import static java.util.Collections.emptyList;
18
import static java.util.stream.Collectors.toList;
19
20
public abstract class InterfaceContractValidator<C, E> {
21
22
    private String communicationInterface;
23
24
    public InterfaceContractValidator(String communicationInterface) {
25
        this.communicationInterface = communicationInterface;
26
    }
27
28
    public String getCommunicationInterface() {
29
        return this.communicationInterface;
30
    }
31
32
    public List<CapabilitiesValidationResult> validateCapabilities(ServiceContracts provider, Collection<ServiceContracts> allConsumers) {
33
        return extractCapabilities(provider)
34
            .map(capabilities -> allConsumers
35
                .stream()
36
                .map(consumer -> validateCapabilities(capabilities, provider.getName(), consumer))
37
                .filter(validationResult -> !validationResult.getInteractionValidationResults().isEmpty())
38
                .collect(toList())
39
            ).orElse(emptyList());
40
    }
41
42
    private CapabilitiesValidationResult validateCapabilities(C capabilities, String providerName, ServiceContracts consumer) {
43
        List<InteractionValidationResult> validatedInteractions = consumer
44
            .getMappedExpectations(providerName, this.communicationInterface, this::asExpectations)
45
            .map(expectations -> validate(expectations, capabilities))
46
            .orElse(emptyList());
47
48
        return new CapabilitiesValidationResult(
49
            consumer.getName(),
50
            consumer.getVersion(),
51
            validatedInteractions
52
        );
53
    }
54
55
    public List<ExpectationValidationResult> validateExpectations(ServiceContracts consumer, Collection<ServiceContracts> allProviders) {
56
        return extractExpectations(consumer)
57
            .entrySet()
58
            .stream()
59
            .flatMap(pe -> validateExpectations(pe.getValue(), pe.getKey(), allProviders))
60
            .collect(toList());
61
    }
62
63
    private Stream<? extends ExpectationValidationResult> validateExpectations(E expectations, String providerName, Collection<ServiceContracts> allProviders) {
64
        List<ServiceContracts> matchedProviders = allProviders
65
            .stream()
66
            .filter(it -> it.getName().equals(providerName))
67
            .collect(toList());
68
        if (matchedProviders.isEmpty()) {
69
            return Stream.of(createProviderNotAvailableResult(providerName));
70
        } else {
71
            return matchedProviders
72
                .stream()
73
                .map(matchedProvider -> validateExpectations(expectations, matchedProvider));
74
        }
75
    }
76
77
    private ExpectationValidationResult validateExpectations(E expectations, ServiceContracts provider) {
78
        List<InteractionValidationResult> validatedInteractions = provider
79
            .getMappedCapabilities(this.communicationInterface, this::asCapabilities)
80
            .map(capabilities -> validate(expectations, capabilities))
81
            .orElseGet(() -> newArrayList(
82
                new InteractionValidationResult(
83
                    "any",
84
                    FAILED,
85
                    newArrayList("provider was registered without any '" + this.communicationInterface + "' capabilities")
86
                )
87
            ));
88
89
        return new ExpectationValidationResult(
90
            provider.getName(),
91
            provider.getVersion(),
92
            validatedInteractions
93
        );
94
    }
95
96
    private ExpectationValidationResult createProviderNotAvailableResult(String providerName) {
97
        return new ExpectationValidationResult(
98
            providerName,
99
            null,
100
            newArrayList(new InteractionValidationResult("any", InteractionValidationStatus.FAILED, newArrayList("provider not available")))
101
        );
102
    }
103
104
    public Optional<C> extractCapabilities(ServiceContracts serviceContracts) {
105
        return serviceContracts.getMappedCapabilities(this.communicationInterface, this::asCapabilities);
106
    }
107
108
    public Map<String, E> extractExpectations(ServiceContracts testedServiceContracts) {
109
        return testedServiceContracts.getMappedExpectations(this.communicationInterface, this::asExpectations);
110
    }
111
112
    public abstract C asCapabilities(String rawCapabilities);
113
114
    public abstract E asExpectations(String rawExpectations);
115
116
    public abstract List<InteractionValidationResult> validate(E expectations, C capabilities);
117
118
    public enum InteractionValidationStatus {
119
120
        OK,
121
        FAILED
122
123
    }
124
125
    @Getter
126
    @AllArgsConstructor
127
    public static class CapabilitiesValidationResult {
128
129
        private String consumerName;
130
        private String consumerVersion;
131
        private List<InteractionValidationResult> interactionValidationResults;
132
133
        public boolean isEmpty() {
134
            return this.interactionValidationResults.isEmpty();
135
        }
136
137
    }
138
139
    @Getter
140
    @AllArgsConstructor
141
    public static class ExpectationValidationResult {
142
143
        private String providerName;
144
        private String providerVersion;
145
146
        private List<InteractionValidationResult> interactionValidationResults;
147
148
    }
149
150
    @Getter
151
    @AllArgsConstructor(access = AccessLevel.PRIVATE)
152
    public static class InteractionValidationResult {
153
154
        private final String name;
155
        private final InteractionValidationStatus status;
156
        private final List<String> errors;
157
158
        public static InteractionValidationResult success(String name) {
159
            return new InteractionValidationResult(name, OK, newArrayList());
160
        }
161
162
        public static InteractionValidationResult fail(String name, List<String> errors) {
163
            return new InteractionValidationResult(name, FAILED, errors);
164
        }
165
    }
166
}
167