Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class OrganizationApiClient extends ApiClient {

private static final String PARTY_CHARACTERISTIC_NAME = "partyCharacteristic.name";
private static final String ORGANIZATION_PATH = "organization";
private static final int PAGE_SIZE = 100;

private final String baseUrl;
private final ObjectMapper objectMapper;
Expand All @@ -61,28 +62,37 @@ public OrganizationVO getOrganization(String tmfId) {
}

public Optional<OrganizationVO> getByDid(String did) {
HttpUrl.Builder urlBuilder = HttpUrl.parse(baseUrl).newBuilder();
urlBuilder.addPathSegment(ORGANIZATION_PATH);
urlBuilder.addQueryParameter(PARTY_CHARACTERISTIC_NAME, PARTY_CHARACTERISTIC_DID);
Request request = new Request.Builder().url(urlBuilder.build()).build();
try (ResponseBody responseBody = executeRequest(request)) {
return objectMapper
.readValue(responseBody.bytes(), new TypeReference<List<OrganizationVO>>() {})
.stream()
.filter(
organizationVO ->
Optional.ofNullable(organizationVO.getPartyCharacteristic())
.orElse(List.of())
.stream()
.filter(
characteristicVO ->
characteristicVO.getName().equals(PARTY_CHARACTERISTIC_DID))
.anyMatch(characteristicVO -> characteristicVO.getValue().equals(did)))
.findAny();
} catch (IOException e) {
monitor.warning("Was not able to get the organization by did.", e);
throw new BadGatewayException("Was not able to get the organization by did.");
// Page through the organizations: the TMForum query only filters by characteristic name,
// so the matching org may sit beyond the first page. Stop on the first match or when a
// short page signals the end, otherwise a present org could be missed and re-created.
Optional<OrganizationVO> match = Optional.empty();
boolean morePages = true;
int offset = 0;
while (match.isEmpty() && morePages) {
HttpUrl.Builder urlBuilder = HttpUrl.parse(baseUrl).newBuilder();
urlBuilder.addPathSegment(ORGANIZATION_PATH);
urlBuilder.addQueryParameter(PARTY_CHARACTERISTIC_NAME, PARTY_CHARACTERISTIC_DID);
urlBuilder.addQueryParameter(OFFSET_PARAM, String.valueOf(offset));
urlBuilder.addQueryParameter(LIMIT_PARAM, String.valueOf(PAGE_SIZE));
Request request = new Request.Builder().url(urlBuilder.build()).build();
try (ResponseBody responseBody = executeRequest(request)) {
List<OrganizationVO> organizations =
objectMapper.readValue(responseBody.bytes(), new TypeReference<>() {});
match = organizations.stream().filter(org -> hasDid(org, did)).findAny();
morePages = organizations.size() == PAGE_SIZE;
offset += PAGE_SIZE;
} catch (IOException e) {
monitor.warning("Was not able to get the organization by did.", e);
throw new BadGatewayException("Was not able to get the organization by did.");
}
}
return match;
}

private static boolean hasDid(OrganizationVO organizationVO, String did) {
return Optional.ofNullable(organizationVO.getPartyCharacteristic()).orElse(List.of()).stream()
.filter(characteristicVO -> characteristicVO.getName().equals(PARTY_CHARACTERISTIC_DID))
.anyMatch(characteristicVO -> characteristicVO.getValue().equals(did));
}

/** Creates the given organization */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public Optional<OrganizationVO> getOrganization(String tmfId) {
}

public String getTmfId(String did) {
return organizationApi.getByDid(did).orElse(createOrganization(did)).getId();
return organizationApi.getByDid(did).orElseGet(() -> createOrganization(did)).getId();
}

private OrganizationVO createOrganization(String did) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import static org.junit.jupiter.api.Assertions.*;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import okhttp3.mockwebserver.RecordedRequest;
import org.eclipse.edc.web.spi.exception.BadGatewayException;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -85,7 +87,8 @@ public void testGetByDid_success() throws Exception {
"The correct organization should be returned.");

RecordedRequest recordedRequest = mockWebServer.takeRequest();
assertEquals("/organization?partyCharacteristic.name=did", recordedRequest.getPath());
assertEquals(
"/organization?partyCharacteristic.name=did&offset=0&limit=100", recordedRequest.getPath());
}

@Test
Expand All @@ -99,7 +102,8 @@ public void testGetByDid_success_multiple_orgs() throws Exception {
"The correct organization should be returned.");

RecordedRequest recordedRequest = mockWebServer.takeRequest();
assertEquals("/organization?partyCharacteristic.name=did", recordedRequest.getPath());
assertEquals(
"/organization?partyCharacteristic.name=did&offset=0&limit=100", recordedRequest.getPath());
}

@Test
Expand All @@ -111,7 +115,8 @@ public void testGetByDid_success_no_org() throws Exception {
"If the organization does not exist, it should not be returned.");

RecordedRequest recordedRequest = mockWebServer.takeRequest();
assertEquals("/organization?partyCharacteristic.name=did", recordedRequest.getPath());
assertEquals(
"/organization?partyCharacteristic.name=did&offset=0&limit=100", recordedRequest.getPath());
}

@Test
Expand All @@ -123,7 +128,33 @@ public void testGetByDid_success_other_orgs() throws Exception {
"If the organization does not exist, it should not be returned.");

RecordedRequest recordedRequest = mockWebServer.takeRequest();
assertEquals("/organization?partyCharacteristic.name=did", recordedRequest.getPath());
assertEquals(
"/organization?partyCharacteristic.name=did&offset=0&limit=100", recordedRequest.getPath());
}

@Test
public void testGetByDid_success_second_page() throws Exception {
// First page is full (100 orgs, none matching) so the loop must fetch a second page,
// where the matching org lives.
List<OrganizationVO> firstPage =
IntStream.range(0, 100)
.mapToObj(i -> getValidOrganization("did:web:other-" + i))
.collect(Collectors.toList());
OrganizationVO testOrganization = getValidOrganization(TEST_ORGANIZATION_DID);
mockResponse(200, firstPage);
mockResponse(200, List.of(testOrganization));

assertEquals(
testOrganization,
organizationApiClient.getByDid(TEST_ORGANIZATION_DID).get(),
"The organization on the second page should be returned.");

assertEquals(
"/organization?partyCharacteristic.name=did&offset=0&limit=100",
mockWebServer.takeRequest().getPath());
assertEquals(
"/organization?partyCharacteristic.name=did&offset=100&limit=100",
mockWebServer.takeRequest().getPath());
}

@Test
Expand Down
Loading