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

FIWARE / contract-management / #31

04 Apr 2025 09:14AM UTC coverage: 1.9% (+0.9%) from 0.982%
#31

Pull #5

wistefan
add json schemas to extend offerings and quotes
Pull Request #5: integrate contract negotiation

29 of 247 new or added lines in 9 files covered. (11.74%)

5 existing lines in 2 files now uncovered.

644 of 33897 relevant lines covered (1.9%)

0.02 hits per line

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

41.46
/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.Map;
18
import java.util.UUID;
19

20

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

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

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

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

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

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

80
        }
81

82
        public Mono<AgreementVO> getAgreement(String processId) {
NEW
83
                return contractApiClient.getAgreement(processId)
×
NEW
84
                                .onErrorMap(t -> {
×
NEW
85
                                        throw new RainbowException("Was not able to create agreement");
×
86
                                })
NEW
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) {
NEW
108
                return contractApiClient.createRequest(negotiationRequestVO)
×
NEW
109
                                .map(HttpResponse::body)
×
NEW
110
                                .map(NegotiationVO::getDspaceColonProviderPid)
×
NEW
111
                                .onErrorMap(t -> {
×
NEW
112
                                        throw new RainbowException("Was not able to create negotiation request.", t);
×
113
                                });
114
        }
115

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

121
        public Mono<ProviderNegotiationVO> getNegotiationProcess(String providerId) {
NEW
122
                return contractApiClient.getProcessById(providerId)
×
NEW
123
                                .map(HttpResponse::body)
×
NEW
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) {
NEW
128
                return contractApiClient.getProcessById(providerId)
×
NEW
129
                                .map(HttpResponse::body)
×
NEW
130
                                .flatMap(pn -> {
×
NEW
131
                                        NegotiationProcessVO negotiationProcessVO = new NegotiationProcessVO()
×
NEW
132
                                                        .dspaceColonConsumerPid(pn.getConsumerId())
×
NEW
133
                                                        .dspaceColonProviderPid(pn.getProviderId())
×
NEW
134
                                                        .dspaceColonState(state);
×
NEW
135
                                        return contractApiClient.updateProcessById(pn.getCnProcessId(), negotiationProcessVO);
×
136
                                })
NEW
137
                                .map(HttpResponse::body)
×
NEW
138
                                .onErrorMap(t -> new RainbowException(String.format("Was not able to update negotiation process %s to %s.", providerId, state), t));
×
139
        }
140

141

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

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

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

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