Skip to content

Commit

Permalink
Merge pull request eclipse-tractusx#463 from catenax-ng/fix/TRI-1460-…
Browse files Browse the repository at this point in the history
…ess-missing-bpn

fix(ess):[TRI-1460] Add BPN to IRS job requests started by ESS
  • Loading branch information
ds-jhartmann authored Aug 10, 2023
2 parents be9d9e7 + 7e12c04 commit b21d549
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 83 deletions.
11 changes: 3 additions & 8 deletions docs/src/api/irs-v1.0.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2163,21 +2163,16 @@ components:
\ There are two uri variable placeholders that can be used: jobId and\
\ jobState."
example: "https://hostname.com/callback?jobId={jobId}&jobState={jobState}"
globalAssetId:
type: string
description: Id of global asset.
example: urn:uuid:6c311d29-5753-46d4-b32c-19b918ea93b0
maxLength: 45
minLength: 45
pattern: "^urn:uuid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
key:
$ref: '#/components/schemas/PartChainIdentificationKey'
incidentBpns:
type: array
items:
type: string
maxItems: 2147483647
required:
- globalAssetId
- incidentBpns
- key
RegisterJob:
type: object
additionalProperties: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.irs.component.JobHandle;
import org.eclipse.tractusx.irs.component.Jobs;
import org.eclipse.tractusx.irs.component.PartChainIdentificationKey;
import org.eclipse.tractusx.irs.component.enums.BomLifecycle;
import org.springframework.stereotype.Service;

Expand All @@ -39,8 +40,8 @@ public class IrsFacade {

private final IrsClient irsClient;

public JobHandle startIrsJob(final String globalAssetId, final BomLifecycle bomLifecycle) {
final JobHandle response = irsClient.startJob(IrsRequest.bpnInvestigations(globalAssetId, bomLifecycle));
public JobHandle startIrsJob(final PartChainIdentificationKey key, final BomLifecycle bomLifecycle) {
final JobHandle response = irsClient.startJob(IrsRequest.bpnInvestigations(key, bomLifecycle));
log.info("Registered IRS job with jobId: {}", response.getId());
return response;
}
Expand Down
29 changes: 9 additions & 20 deletions irs-ess/src/main/java/org/eclipse/tractusx/ess/irs/IrsRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,49 +26,38 @@

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Value;
import org.eclipse.tractusx.irs.component.PartChainIdentificationKey;
import org.eclipse.tractusx.irs.component.enums.BomLifecycle;

/**
* Irs Request for IRS API
* Irs Request for IRS API
*/
@Value
@Builder(toBuilder = true)
@AllArgsConstructor
class IrsRequest {
private IdentificationKey key;
private PartChainIdentificationKey key;
private String bomLifecycle;
private List<String> aspects;
private boolean collectAspects;
private int depth;

/**
* Predefined request body for SupplyChain processing
* @param globalAssetId id
*
* @param key the key to identify the asset
* @param bomLifecycle lifecycle - default is asPlanned
* @return request body
*/
/* package */ static IrsRequest bpnInvestigations(final String globalAssetId, final BomLifecycle bomLifecycle) {
/* package */ static IrsRequest bpnInvestigations(final PartChainIdentificationKey key, final BomLifecycle bomLifecycle) {
return IrsRequest.builder()
.key(IdentificationKey.builder().globalAssetId(globalAssetId).build())
.bomLifecycle(bomLifecycle != null
? bomLifecycle.getName() : BomLifecycle.AS_PLANNED.getName())
.key(key)
.bomLifecycle(
bomLifecycle != null ? bomLifecycle.getName() : BomLifecycle.AS_PLANNED.getName())
.depth(1)
.collectAspects(false)
.build();
}

/**
* Key object contains required attributes for identify part chain entry node
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
/* package */ static class IdentificationKey {
private String globalAssetId;
private String bpn;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.UUID;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.irs.component.PartChainIdentificationKey;
import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification;
import org.eclipse.tractusx.irs.component.JobHandle;
import org.eclipse.tractusx.irs.component.RegisterBpnInvestigationJob;
Expand Down Expand Up @@ -72,23 +73,31 @@ public void handleNotification(final EdcNotification notification) {
final List<String> concernedCatenaXIds = getConcernedCatenaXIds(concernedCatenaXIdsNotification);

final List<UUID> createdJobs = concernedCatenaXIds.stream()
.map(catenaXId -> essService.startIrsJob(
RegisterBpnInvestigationJob.builder()
.incidentBpns(List.of(bpn))
.globalAssetId(catenaXId)
.build()))
.map(JobHandle::getId)
.toList();
.map(catenaXId -> startIrsJob(bpn, catenaXId))
.map(JobHandle::getId)
.toList();
relatedInvestigationJobsCache.store(notification.getHeader().getNotificationId(),
new RelatedInvestigationJobs(notification, createdJobs));
}
}

private JobHandle startIrsJob(final String bpn, final String catenaXId) {
final var job = RegisterBpnInvestigationJob.builder()
.incidentBpns(List.of(bpn))
.key(PartChainIdentificationKey.builder()
.globalAssetId(catenaXId)
.bpn(localBpn)
.build())
.build();

return essService.startIrsJob(job);
}

@NotNull
private static List<String> getConcernedCatenaXIds(final Optional<Object> concernedCatenaXIdsNotification) {
final List<String> concernedCatenaXIds = new ArrayList<>();
concernedCatenaXIdsNotification.ifPresent(list -> concernedCatenaXIds.addAll(
((List<String>) list).stream().toList()));
concernedCatenaXIdsNotification.ifPresent(
list -> concernedCatenaXIds.addAll(((List<String>) list).stream().toList()));
return concernedCatenaXIds;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification;
import org.eclipse.tractusx.ess.irs.IrsFacade;
import org.eclipse.tractusx.irs.component.JobHandle;
import org.eclipse.tractusx.irs.component.Jobs;
import org.eclipse.tractusx.irs.component.RegisterBpnInvestigationJob;
import org.eclipse.tractusx.irs.component.enums.JobState;
import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;
Expand All @@ -51,7 +51,7 @@ public class EssService {
private final EssRecursiveNotificationHandler recursiveNotificationHandler;

public JobHandle startIrsJob(final RegisterBpnInvestigationJob request) {
final JobHandle jobHandle = irsFacade.startIrsJob(request.getGlobalAssetId(), request.getBomLifecycle());
final JobHandle jobHandle = irsFacade.startIrsJob(request.getKey(), request.getBomLifecycle());

final UUID createdJobId = jobHandle.getId();
final Jobs createdJob = irsFacade.getIrsJob(createdJobId.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.eclipse.tractusx.ess.service.EssService;
import org.eclipse.tractusx.irs.component.JobHandle;
import org.eclipse.tractusx.irs.component.Jobs;
import org.eclipse.tractusx.irs.component.PartChainIdentificationKey;
import org.eclipse.tractusx.irs.component.RegisterBpnInvestigationJob;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -61,12 +62,13 @@ class EssControllerTest {
@Test
@WithMockUser(authorities = "view_irs")
void shouldRegisterBpnInvestigationForValidRequest() throws Exception {
when(essService.startIrsJob(any(RegisterBpnInvestigationJob.class))).thenReturn(JobHandle.builder().id(UUID.randomUUID()).build());
when(essService.startIrsJob(any(RegisterBpnInvestigationJob.class))).thenReturn(
JobHandle.builder().id(UUID.randomUUID()).build());

this.mockMvc.perform(post(path).with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(new ObjectMapper().writeValueAsString(reqBody(globalAssetId, List.of(bpn)))))
.andExpect(status().isCreated());
.contentType(MediaType.APPLICATION_JSON)
.content(new ObjectMapper().writeValueAsString(
reqBody(globalAssetId, List.of(bpn))))).andExpect(status().isCreated());
}

@Test
Expand All @@ -75,31 +77,37 @@ void shouldGetJob() throws Exception {
final String jobId = UUID.randomUUID().toString();
when(essService.getIrsJob(jobId)).thenReturn(Jobs.builder().build());

this.mockMvc.perform(get(path + "/" + jobId))
.andExpect(status().isOk());
this.mockMvc.perform(get(path + "/" + jobId)).andExpect(status().isOk());
}

@Test
@WithMockUser(authorities = "view_irs")
void shouldReturnBadRequestForWrongGlobalAssetId() throws Exception {
this.mockMvc.perform(post(path).with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(new ObjectMapper().writeValueAsString(reqBody("wrongGlobalAssetId", List.of(bpn)))))
.content(new ObjectMapper().writeValueAsString(
reqBody("wrongGlobalAssetId", List.of(bpn)))))
.andExpect(status().isBadRequest());
}

@Test
@WithMockUser(authorities = "view_irs")
void shouldReturnBadRequestForWrongBpn() throws Exception {
this.mockMvc.perform(post(path).with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(new ObjectMapper().writeValueAsString(reqBody(globalAssetId, List.of(bpn, "WRONG_BPN")))))
.contentType(MediaType.APPLICATION_JSON)
.content(new ObjectMapper().writeValueAsString(
reqBody(globalAssetId, List.of(bpn, "WRONG_BPN")))))
.andExpect(status().isBadRequest());
}

RegisterBpnInvestigationJob reqBody(final String globalAssetId, final List<String> bpns) {
return RegisterBpnInvestigationJob.builder().globalAssetId(globalAssetId).incidentBpns(bpns).build();
return RegisterBpnInvestigationJob.builder()
.key(PartChainIdentificationKey.builder()
.globalAssetId(globalAssetId)
.bpn(bpn)
.build())
.incidentBpns(bpns)
.build();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.eclipse.tractusx.irs.component.Job;
import org.eclipse.tractusx.irs.component.JobHandle;
import org.eclipse.tractusx.irs.component.Jobs;
import org.eclipse.tractusx.irs.component.PartChainIdentificationKey;
import org.eclipse.tractusx.irs.component.enums.JobState;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
Expand All @@ -48,7 +49,8 @@ class IrsClientTest {
void shouldStartJob() {
// given
IrsClient irsClient = new IrsClient(restTemplate, URL);
IrsRequest irsRequest = IrsRequest.builder().key(IrsRequest.IdentificationKey.builder().globalAssetId("global-id").build()).bomLifecycle("asBuilt").build();
IrsRequest irsRequest = IrsRequest.builder().key(
PartChainIdentificationKey.builder().globalAssetId("global-id").bpn("BPNL0000000000DD").build()).bomLifecycle("asBuilt").build();
JobHandle expectedResponse = JobHandle.builder().id(UUID.fromString(JOB_ID)).build();

given(restTemplate.postForObject(URL + "/irs/jobs",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.eclipse.tractusx.irs.component.Job;
import org.eclipse.tractusx.irs.component.JobHandle;
import org.eclipse.tractusx.irs.component.Jobs;
import org.eclipse.tractusx.irs.component.PartChainIdentificationKey;
import org.eclipse.tractusx.irs.component.enums.BomLifecycle;
import org.eclipse.tractusx.irs.component.enums.JobState;
import org.junit.jupiter.api.Test;
Expand All @@ -54,10 +55,10 @@ void shouldFetchIrsJobResponse() {
// given
final UUID jobId = UUID.randomUUID();
final Jobs expectedResponse = Jobs.builder()
.job(Job.builder().state(JobState.COMPLETED).id(jobId).build())
.relationships(new ArrayList<>())
.shells(new ArrayList<>())
.build();
.job(Job.builder().state(JobState.COMPLETED).id(jobId).build())
.relationships(new ArrayList<>())
.shells(new ArrayList<>())
.build();

given(irsClient.getJobDetails(jobId.toString())).willReturn(expectedResponse);

Expand All @@ -77,7 +78,13 @@ void shouldStartIrsJobAndReturnJobId() {
given(irsClient.startJob(any())).willReturn(JobHandle.builder().id(jobId).build());

// when
final JobHandle actualResponse = irsFacade.startIrsJob(UUID.randomUUID().toString(), BomLifecycle.AS_PLANNED);
final JobHandle actualResponse = irsFacade.startIrsJob(PartChainIdentificationKey.builder()
.globalAssetId(
UUID.randomUUID()
.toString())
.bpn("BPNL000000000DD")
.build(),
BomLifecycle.AS_PLANNED);

// then
assertThat(actualResponse).isEqualTo(expectedResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,32 +36,39 @@
import java.util.Map;
import java.util.UUID;

import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification;
import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotificationHeader;
import org.eclipse.tractusx.ess.irs.IrsFacade;
import org.eclipse.tractusx.irs.component.GlobalAssetIdentification;
import org.eclipse.tractusx.irs.component.Job;
import org.eclipse.tractusx.irs.component.JobHandle;
import org.eclipse.tractusx.irs.component.Jobs;
import org.eclipse.tractusx.irs.component.PartChainIdentificationKey;
import org.eclipse.tractusx.irs.component.RegisterBpnInvestigationJob;
import org.eclipse.tractusx.irs.component.enums.JobState;
import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification;
import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotificationHeader;
import org.junit.jupiter.api.Test;
import org.springframework.web.server.ResponseStatusException;

class EssServiceTest {

private final IrsFacade irsFacade = mock(IrsFacade.class);
private final BpnInvestigationJobCache bpnInvestigationJobCache = new InMemoryBpnInvestigationJobCache();
private final EssRecursiveNotificationHandler recursiveNotificationHandler = mock(EssRecursiveNotificationHandler.class);
private final EssService essService = new EssService(irsFacade, bpnInvestigationJobCache, recursiveNotificationHandler);
private final EssRecursiveNotificationHandler recursiveNotificationHandler = mock(
EssRecursiveNotificationHandler.class);
private final EssService essService = new EssService(irsFacade, bpnInvestigationJobCache,
recursiveNotificationHandler);

@Test
void shouldSuccessfullyStartJobAndReturnWithExtendedSubmodelList() {
final String globalAssetId = UUID.randomUUID().toString();
final List<String> bpns = List.of("BPNS000000000DDD");
final UUID createdJobId = UUID.randomUUID();
final var key = PartChainIdentificationKey.builder()
.globalAssetId(globalAssetId)
.bpn("BPNS0000000000DD")
.build();
final RegisterBpnInvestigationJob request = RegisterBpnInvestigationJob.builder()
.globalAssetId(globalAssetId)
.key(key)
.incidentBpns(bpns)
.build();
final Jobs expectedResponse = Jobs.builder()
Expand All @@ -74,7 +81,7 @@ void shouldSuccessfullyStartJobAndReturnWithExtendedSubmodelList() {
.shells(new ArrayList<>())
.build();

when(irsFacade.startIrsJob(eq(globalAssetId), any())).thenReturn(JobHandle.builder().id(createdJobId).build());
when(irsFacade.startIrsJob(eq(key), any())).thenReturn(JobHandle.builder().id(createdJobId).build());
when(irsFacade.getIrsJob(createdJobId.toString())).thenReturn(expectedResponse);

final JobHandle jobHandle = essService.startIrsJob(request);
Expand Down
Loading

0 comments on commit b21d549

Please sign in to comment.