• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FIWARE / contract-management / #58

19 Aug 2025 07:56AM UTC coverage: 1.654% (-0.07%) from 1.725%
#58

push

web-flow
Merge pull request #10 from FIWARE/policy-support

Policy support

2 of 67 new or added lines in 4 files covered. (2.99%)

25 existing lines in 3 files now uncovered.

559 of 33806 relevant lines covered (1.65%)

0.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/java/org/fiware/iam/tmforum/PolicyResolver.java
1
package org.fiware.iam.tmforum;
2

3
import com.fasterxml.jackson.core.type.TypeReference;
4
import com.fasterxml.jackson.databind.ObjectMapper;
5
import io.micronaut.http.HttpResponse;
6
import jakarta.inject.Singleton;
7
import lombok.RequiredArgsConstructor;
8
import lombok.extern.slf4j.Slf4j;
9
import org.fiware.iam.til.model.CredentialsVO;
10
import org.fiware.iam.tmforum.productcatalog.api.ProductOfferingApiClient;
11
import org.fiware.iam.tmforum.productcatalog.api.ProductSpecificationApiClient;
12
import org.fiware.iam.tmforum.productcatalog.model.ProductSpecificationRefVO;
13
import org.fiware.iam.tmforum.productcatalog.model.*;
14
import org.fiware.iam.tmforum.productorder.model.ProductOfferingRefVO;
15
import org.fiware.iam.tmforum.productorder.model.*;
16
import org.fiware.iam.tmforum.quote.api.QuoteApiClient;
17
import org.fiware.iam.tmforum.quote.model.QuoteItemVO;
18
import org.fiware.iam.tmforum.quote.model.QuoteStateTypeVO;
19
import org.fiware.iam.tmforum.quote.model.QuoteVO;
20
import reactor.core.publisher.Mono;
21

22
import java.util.List;
23
import java.util.Map;
24
import java.util.Objects;
25
import java.util.stream.Stream;
26

27
/**
28
 * Extract policies from ProductOrders, either from the connected Quote or ProductSpec.
29
 */
30
@Singleton
NEW
31
@Slf4j
×
32
@RequiredArgsConstructor
33
public class PolicyResolver {
34

35
        private static final String AUTHORIZATION_POLICY_KEY = "authorizationPolicy";
36
        private static final String QUOTE_DELETE_ACTION = "delete";
37

38
        private final ProductOfferingApiClient productOfferingApiClient;
39
        private final ProductSpecificationApiClient productSpecificationApiClient;
40
        private final QuoteApiClient quoteApiClient;
41
        private final ObjectMapper objectMapper;
42

43
        public Mono<List<Map<String, Object>>> getAuthorizationPolicy(ProductOrderVO productOrder) {
NEW
44
                if (productOrder.getQuote() != null && !productOrder.getQuote().isEmpty()) {
×
NEW
45
                        return getAuthorizationPolicyFromQuote(productOrder.getQuote());
×
46
                }
NEW
47
                log.debug("No quote found, take the original offer from the order item.");
×
NEW
48
                List<Mono<List<Map<String, Object>>>> credentialsVOMonoList = productOrder.getProductOrderItem()
×
NEW
49
                                .stream()
×
NEW
50
                                .filter(poi -> poi.getAction() == OrderItemActionTypeVO.ADD || poi.getAction() == OrderItemActionTypeVO.MODIFY)
×
NEW
51
                                .map(ProductOrderItemVO::getProductOffering)
×
NEW
52
                                .map(ProductOfferingRefVO::getId)
×
NEW
53
                                .map(this::getAuthorizationPolicyFromOffer)
×
NEW
54
                                .toList();
×
55

NEW
56
                return zipMonoList(credentialsVOMonoList);
×
57
        }
58

59
        private Mono<List<Map<String, Object>>> zipMonoList(List<Mono<List<Map<String, Object>>>> monoList) {
NEW
60
                return Mono.zip(monoList, results -> Stream.of(results).map(r -> (List<Map<String, Object>>) r).flatMap(List::stream).toList());
×
61

62
        }
63

64
        private Mono<List<Map<String, Object>>> getAuthorizationPolicyFromOffer(String offerId) {
NEW
65
                return productOfferingApiClient
×
NEW
66
                                .retrieveProductOffering(offerId, null)
×
NEW
67
                                .map(HttpResponse::body)
×
NEW
68
                                .map(ProductOfferingVO::getProductSpecification)
×
NEW
69
                                .map(ProductSpecificationRefVO::getId)
×
NEW
70
                                .flatMap(specId -> productSpecificationApiClient.retrieveProductSpecification(specId, null))
×
NEW
71
                                .map(HttpResponse::body)
×
NEW
72
                                .map(ProductSpecificationVO::getProductSpecCharacteristic)
×
NEW
73
                                .map(this::getAuthorizationPolicyFromPSC);
×
74
        }
75

76
        private Mono<List<Map<String, Object>>> getAuthorizationPolicyFromQuote(List<QuoteRefVO> quoteRefVOS) {
NEW
77
                return zipMonoList(quoteRefVOS.stream()
×
NEW
78
                                .map(QuoteRefVO::getId)
×
NEW
79
                                .map(quoteId -> quoteApiClient.retrieveQuote(quoteId, null)
×
NEW
80
                                                .map(HttpResponse::body)
×
NEW
81
                                                .filter(quoteVO -> quoteVO.getState() == QuoteStateTypeVO.ACCEPTED)
×
NEW
82
                                                .map(QuoteVO::getQuoteItem)
×
NEW
83
                                                .flatMap(quoteItemList -> {
×
NEW
84
                                                        List<Mono<List<Map<String, Object>>>> configMonos = quoteItemList.stream()
×
NEW
85
                                                                        .filter(item -> item.getState().equals(QuoteStateTypeVO.ACCEPTED.getValue()))
×
NEW
86
                                                                        .filter(item -> !item.getAction().equals(QUOTE_DELETE_ACTION))
×
NEW
87
                                                                        .map(QuoteItemVO::getProductOffering)
×
NEW
88
                                                                        .map(org.fiware.iam.tmforum.quote.model.ProductOfferingRefVO::getId)
×
NEW
89
                                                                        .map(this::getAuthorizationPolicyFromOffer)
×
NEW
90
                                                                        .toList();
×
NEW
91
                                                        return zipMonoList(configMonos);
×
92
                                                }))
NEW
93
                                .toList());
×
94
        }
95

96
        private List<Map<String, Object>> getAuthorizationPolicyFromPSC(List<ProductSpecificationCharacteristicVO> pscList) {
NEW
97
                return pscList.stream()
×
NEW
98
                                .filter(psc -> psc.getValueType().equals(AUTHORIZATION_POLICY_KEY))
×
NEW
99
                                .findFirst()
×
NEW
100
                                .map(productSpecificationCharacteristicVO -> productSpecificationCharacteristicVO
×
NEW
101
                                                .getProductSpecCharacteristicValue()
×
NEW
102
                                                .stream()
×
NEW
103
                                                .map(CharacteristicValueSpecificationVO::getValue)
×
NEW
104
                                                .map(value -> {
×
105
                                                        try {
NEW
106
                                                                List<Map<String, Object>> policies = objectMapper.convertValue(value, new TypeReference<List<Map<String, Object>>>() {
×
107
                                                                });
NEW
108
                                                                log.debug("Policy is {}", policies);
×
NEW
109
                                                                return policies;
×
NEW
110
                                                        } catch (IllegalArgumentException iae) {
×
NEW
111
                                                                log.warn("The characteristic value is invalid.", iae);
×
NEW
112
                                                                return null;
×
113
                                                        }
114
                                                })
NEW
115
                                                .filter(Objects::nonNull)
×
NEW
116
                                                .flatMap(List::stream)
×
NEW
117
                                                .toList()).orElseGet(List::of);
×
118
        }
119
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc