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

FIWARE / contract-management / #48

06 Aug 2025 11:35AM UTC coverage: 1.655% (-0.2%) from 1.815%
#48

Pull #8

wistefan
fixes
Pull Request #8: Support multiple creds

2 of 60 new or added lines in 3 files covered. (3.33%)

25 existing lines in 3 files now uncovered.

558 of 33725 relevant lines covered (1.65%)

0.02 hits per line

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

26.83
/src/main/java/org/fiware/iam/dsp/RainbowAdapter.java
1
package org.fiware.iam.dsp;
2

3
import com.fasterxml.jackson.databind.ObjectMapper;
4
import io.micronaut.http.HttpResponse;
5
import io.micronaut.http.HttpStatus;
6
import io.micronaut.http.client.exceptions.HttpClientResponseException;
7
import jakarta.inject.Singleton;
8
import lombok.RequiredArgsConstructor;
9
import lombok.extern.slf4j.Slf4j;
10
import org.fiware.iam.exception.RainbowException;
11
import org.fiware.rainbow.api.AgreementApiClient;
12
import org.fiware.rainbow.api.ContractApiClient;
13
import org.fiware.rainbow.api.ParticipantApiClient;
14
import org.fiware.rainbow.model.*;
15
import reactor.core.publisher.Mono;
16

17
import java.util.List;
18
import java.util.Map;
19
import java.util.UUID;
20

21

22
/**
23
 * Adapter to handle communication with Rainbow.
24
 */
25
@Singleton
26
@RequiredArgsConstructor
27
@Slf4j
1✔
28
public class RainbowAdapter {
29

30
        private final AgreementApiClient agreementApiClient;
31
        private final ContractApiClient contractApiClient;
32
        private final ParticipantApiClient participantApiClient;
33
        private final ObjectMapper objectMapper;
34

35
        /**
36
         * Create the agreement for the given organization and offer
37
         */
38
        public Mono<AgreementVO> createAgreement(String organizationId, String offeringId) {
39
                AgreementCreateVO agreementCreateVO = new AgreementCreateVO()
1✔
40
                                .identity(organizationId)
1✔
41
                                .dataServiceId(offeringId);
1✔
42

43
                return agreementApiClient
1✔
44
                                .createAgreement(agreementCreateVO)
1✔
45
                                .map(HttpResponse::body)
1✔
46
                                .map(body -> objectMapper.convertValue(body, AgreementVO.class))
1✔
47
                                .onErrorMap(t -> {
1✔
48
                                        throw new RainbowException("Was not able to create agreement");
1✔
49
                                });
50
        }
51

52
        private Mono<LastOfferVO> getTheLastOffer(String processId) {
53
                return contractApiClient.getLastOfferForProcess(processId)
×
54
                                .map(HttpResponse::body)
×
55
                                .onErrorMap(t -> new RainbowException(String.format("Was not able to find the last offer for %s.", processId)));
×
56
        }
57

58
        public Mono<AgreementVO> createAgreementAfterNegotiation(String providerId, String consumerOrganization, String providerOrganization) {
59
                return getNegotiationProcess(providerId)
×
60
                                .flatMap(providerNegotiationVO ->
×
61
                                                getTheLastOffer(providerNegotiationVO.getCnProcessId())
×
62
                                                                .flatMap(lastOfferVO -> {
×
63
                                                                        OdrlAgreementVO agreementVO = new OdrlAgreementVO()
×
64
                                                                                        .atId("urn:uuid:" + UUID.randomUUID())
×
65
                                                                                        .odrlColonTarget(lastOfferVO.getOfferContent().getOdrlColonTarget())
×
66
                                                                                        .odrlColonAssignee(prefixDid(consumerOrganization))
×
67
                                                                                        .odrlColonAssigner(prefixDid(providerOrganization))
×
68
                                                                                        .odrlColonPermission(lastOfferVO.getOfferContent().getOdrlColonPermission());
×
69
                                                                        if (lastOfferVO.getOfferContent().getOdrlColonObligation() != null && lastOfferVO.getOfferContent().getOdrlColonObligation().isEmpty()) {
×
70
                                                                                agreementVO.odrlColonObligation(lastOfferVO.getOfferContent().getOdrlColonObligation());
×
71
                                                                        }
72
                                                                        AgreementRequestVO agreementRequestVO = new AgreementRequestVO()
×
73
                                                                                        .dspaceColonProviderParticipantId(prefixDid(providerOrganization))
×
74
                                                                                        .dspaceColonConsumerParticipantId(prefixDid(consumerOrganization))
×
75
                                                                                        .odrlColonAgreement(agreementVO);
×
76
                                                                        return contractApiClient.createAgreementForProcess(providerNegotiationVO.getCnProcessId(), lastOfferVO.getCnMessageId(), agreementRequestVO);
×
77
                                                                }))
78
                                .map(HttpResponse::body)
×
79
                                .map(r -> new AgreementVO())
×
80
                                .onErrorMap(t -> new RainbowException("Was not able to create agreement"));
×
81

82
        }
83

84
        public Mono<AgreementVO> getAgreement(String processId) {
85
                return contractApiClient.getAgreement(processId)
×
86
                                .onErrorMap(t -> new RainbowException("Was not able to create agreement"))
×
87
                                .map(HttpResponse::body);
×
88
        }
89

90
        /**
91
         * Delete the agreement with the given id
92
         */
93
        public Mono<Boolean> deleteAgreement(String agreementId) {
94
                return agreementApiClient.deleteAgreementById(agreementId)
1✔
95
                                .map(objectHttpResponse -> {
1✔
96
                                        if (objectHttpResponse.status().equals(HttpStatus.ACCEPTED)) {
1✔
97
                                                return true;
1✔
98
                                        }
99
                                        return false;
1✔
100
                                })
101
                                .onErrorResume(t -> Mono.just(false));
1✔
102
        }
103

104
        /**
105
         * Create the given negotiation request at rainbow and return the providerId
106
         */
107
        public Mono<String> createNegotiationRequest(NegotiationRequestVO negotiationRequestVO) {
108
                return contractApiClient.createRequest(negotiationRequestVO)
×
109
                                .map(HttpResponse::body)
×
110
                                .map(NegotiationVO::getDspaceColonProviderPid)
×
111
                                .onErrorMap(t -> {
×
112
                                        throw new RainbowException("Was not able to create negotiation request.", t);
×
113
                                });
114
        }
115

116
        public Mono<String> getNegotiationProcessState(String providerId) {
117
                return getNegotiationProcess(providerId)
×
118
                                .map(ProviderNegotiationVO::getState);
×
119
        }
120

121
        public Mono<ProviderNegotiationVO> getNegotiationProcess(String providerId) {
122
                return contractApiClient.getProcessById(providerId)
×
123
                                .map(HttpResponse::body)
×
124
                                .onErrorMap(t -> new RainbowException(String.format("Was not able to find negotiation process %s.", providerId), t));
×
125
        }
126

127
        public Mono<Object> updateNegotiationProcessByProviderId(String providerId, String state) {
128
                return contractApiClient.getProcessById(providerId)
×
129
                                .map(HttpResponse::body)
×
130
                                .flatMap(pn -> {
×
131
                                        NegotiationProcessVO negotiationProcessVO = new NegotiationProcessVO()
×
132
                                                        .dspaceColonConsumerPid(pn.getConsumerId())
×
133
                                                        .dspaceColonProviderPid(pn.getProviderId())
×
134
                                                        .dspaceColonState(state);
×
135

136
                                        return contractApiClient.updateProcessById(pn.getCnProcessId(), negotiationProcessVO);
×
137
                                })
138
                                .map(HttpResponse::body)
×
139
                                .onErrorMap(t -> new RainbowException(String.format("Was not able to update negotiation process %s to %s.", providerId, state), t));
×
140
        }
141

142

143
        public Mono<Boolean> isParticipant(String id) {
144
                return participantApiClient.getParticipantById(prefixDid(id))
1✔
145
                                .map(r -> true)
1✔
146
                                .onErrorResume(t -> {
1✔
147
                                        if (t instanceof HttpClientResponseException re && re.getStatus().equals(HttpStatus.NOT_FOUND)) {
1✔
UNCOV
148
                                                return Mono.just(false);
×
149
                                        }
150
                                        throw new RainbowException(String.format("Was not able to check participant %s.", id), t);
1✔
151
                                });
152
        }
153

154
        public Mono<String> createParticipant(String participantId, String participantType) {
UNCOV
155
                return isParticipant(participantId)
×
UNCOV
156
                                .filter(r -> !r)
×
UNCOV
157
                                .flatMap(p -> participantApiClient.createParticipant(new ParticipantVO()
×
UNCOV
158
                                                                .dspaceColonParticipantId(prefixDid(participantId))
×
UNCOV
159
                                                                .dspaceColonParticipantType(participantType)
×
160
                                                                // set empty, rainbow does not support null
UNCOV
161
                                                                .dspaceColonParticipantBaseUrl("")
×
UNCOV
162
                                                                .dspaceColonExtraFields(Map.of()))
×
UNCOV
163
                                                .onErrorMap(t -> {
×
164
                                                        throw new RainbowException(String.format("Was not able to create the participant %s with type %s.", participantId, participantType), t);
×
165
                                                })
UNCOV
166
                                                .map(HttpResponse::body)
×
UNCOV
167
                                                .map(ParticipantVO::getDspaceColonParticipantId))
×
UNCOV
168
                                .defaultIfEmpty(prefixDid(participantId));
×
169
        }
170

171
        private static String prefixDid(String did) {
172
                return String.format("urn:%s", did);
1✔
173
        }
174

175
        private static String removeUrnPrefix(String urnDid) {
176
                return urnDid.replaceFirst("urn:", "");
×
177
        }
178
}
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