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

FIWARE / contract-management / #67

27 Oct 2025 12:33PM UTC coverage: 1.686% (+0.04%) from 1.651%
#67

Pull #12

wistefan
wait for the policy
Pull Request #12: Support for central marketplace and policy creation

117 of 1238 new or added lines in 31 files covered. (9.45%)

5 existing lines in 2 files now uncovered.

587 of 34807 relevant lines covered (1.69%)

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.context.annotation.Requires;
5
import io.micronaut.http.HttpResponse;
6
import io.micronaut.http.HttpStatus;
7
import io.micronaut.http.client.exceptions.HttpClientResponseException;
8
import jakarta.inject.Singleton;
9
import lombok.RequiredArgsConstructor;
10
import lombok.extern.slf4j.Slf4j;
11
import org.fiware.iam.configuration.GeneralProperties;
12
import org.fiware.iam.exception.RainbowException;
13
import org.fiware.rainbow.api.AgreementApiClient;
14
import org.fiware.rainbow.api.ContractApiClient;
15
import org.fiware.rainbow.api.ParticipantApiClient;
16
import org.fiware.rainbow.model.*;
17
import reactor.core.publisher.Mono;
18

19
import java.util.List;
20
import java.util.Map;
21
import java.util.UUID;
22

23

24
/**
25
 * Adapter to handle communication with Rainbow.
26
 */
27
@Requires(condition = GeneralProperties.RainbowCondition.class)
28
@Singleton
29
@RequiredArgsConstructor
30
@Slf4j
1✔
31
public class RainbowAdapter {
32

33
    private final AgreementApiClient agreementApiClient;
34
    private final ContractApiClient contractApiClient;
35
    private final ParticipantApiClient participantApiClient;
36
    private final ObjectMapper objectMapper;
37

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

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

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

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

85
    }
86

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

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

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

119
    public Mono<String> getNegotiationProcessState(String providerId) {
NEW
120
        return getNegotiationProcess(providerId)
×
NEW
121
                .map(ProviderNegotiationVO::getState);
×
122
    }
123

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

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

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

145

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

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

174
    private static String prefixDid(String did) {
175
        return String.format("urn:%s", did);
1✔
176
    }
177

178
    private static String removeUrnPrefix(String urnDid) {
NEW
179
        return urnDid.replaceFirst("urn:", "");
×
180
    }
181
}
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