Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: TRACEFOSS-XXX increase code coverage and refactor exception handling #392

Merged
merged 3 commits into from
Jul 11, 2023
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
2 changes: 2 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@
<sonar.exclusions>
tx-backend/src/main/java/org/eclipse/tractusx/traceability/TraceabilityApplication.java,
tx-backend/src/main/java/org/eclipse/tractusx/traceability/infrastructure/edc/blackbox/HttpCallService.java,
**/*Config.java,
**/*Properties.java
</sonar.exclusions>
</properties>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@ public class BadRequestException extends RuntimeException {
public BadRequestException(String message) {
super(message);
}

public BadRequestException(String message, Throwable cause) {
super(message, cause);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public void startEDCTransfer(QualityNotificationMessage notification, String rec

if (catalog.getDatasets().isEmpty()) {
log.info("No Dataset in catalog found");
throw new BadRequestException("Notication method and type not found.");
throw new BadRequestException("The dataset from the catalog is empty.");
}

Optional<Dataset> filteredDataset = catalog.getDatasets().stream()
Expand Down Expand Up @@ -130,7 +130,7 @@ public void startEDCTransfer(QualityNotificationMessage notification, String rec

if (catalogItem.isEmpty()) {
log.info("No Catalog Item in catalog found");
throw new BadRequestException("No Catalog Item in catalog found");
throw new BadRequestException("No Catalog Item in catalog found.");
}

final String negotiationId = edcService.initializeContractNegotiation(receiverEdcUrl, catalogItem.get(), senderEdcUrl, header);
Expand Down Expand Up @@ -172,9 +172,7 @@ public void startEDCTransfer(QualityNotificationMessage notification, String rec

log.info(":::: EDC Data Transfer Completed :::::");
} catch (IOException e) {
log.error("EDC Data Transfer fail", e);

throw new BadRequestException("EDC Data Transfer fail");
throw new BadRequestException("EDC Data Transfer fail.", e);
} catch (InterruptedException e) {
log.error("Exception", e);
Thread.currentThread().interrupt();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.HttpUrl;
import org.eclipse.edc.catalog.spi.Catalog;
import org.eclipse.edc.catalog.spi.Dataset;
import org.eclipse.tractusx.traceability.infrastructure.edc.blackbox.cache.EndpointDataReference;
import org.eclipse.tractusx.traceability.infrastructure.edc.blackbox.cache.InMemoryEndpointDataReferenceCache;
import org.eclipse.tractusx.traceability.infrastructure.edc.blackbox.configuration.JsonLdConfiguration;
import org.eclipse.tractusx.traceability.infrastructure.edc.properties.EdcProperties;
import org.eclipse.tractusx.traceability.qualitynotification.domain.model.QualityNotificationMessage;
import org.eclipse.tractusx.traceability.qualitynotification.domain.model.QualityNotificationType;
Expand All @@ -38,7 +40,11 @@

import java.io.IOException;
import java.time.Instant;
import java.util.Collections;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;
Expand Down Expand Up @@ -104,8 +110,126 @@ void test_startEDCTransfer() throws IOException, InterruptedException {
verify(endpointDataReferenceCache, times(2)).get(anyString());
verify(objectMapper).writeValueAsString(any());
verify(httpCallService).getUrl(any(), any(), any());
}

@Test
void test_startEDCTransfer_with_catalog_properties() throws IOException, InterruptedException {
//GIVEN
String receiverEdcUrl = "https://example.com/receiver-edcUrl";
String senderEdcUrl = "https://example.com/sender-edcUrl";

QualityNotificationMessage qualityNotificationMessage = NotificationTestDataFactory
.createNotificationTestData(QualityNotificationType.INVESTIGATION);

when(edcProperties.getApiAuthKey()).thenReturn("x-api-key");

Map<String, Object> properties = Map.of(JsonLdConfiguration.NAMESPACE_EDC_PARTICIPANT_ID, "participantId");
Catalog catalog = CatalogTestDataFactory.createCatalogTestData(properties);
when(edcService.getCatalog(anyString(), anyString(), any())).thenReturn(catalog);

when(edcService.initializeContractNegotiation(anyString(), any(), anyString(), any()))
.thenReturn("negotiationId");

Algorithm algorithm = Algorithm.HMAC256("Catena-X");

Check failure

Code scanning / CodeQL

Hard-coded credential in API call

Hard-coded value flows to [sensitive API call](1).
String jwtToken = JWT.create().withExpiresAt(Instant.now()).sign(algorithm);
EndpointDataReference endpointDataReference = EndpointDataReference.Builder.newInstance()
.endpoint("")
.authCode(jwtToken)
.authKey("authKey")
.build();
when(endpointDataReferenceCache.get(anyString())).thenReturn(endpointDataReference);

when(objectMapper.writeValueAsString(any())).thenReturn("someValidJson");

when(httpCallService.getUrl(any(), any(), any())).thenReturn(HttpUrl.get("https://w3id.org"));

//WHEN
investigationsEDCFacade.startEDCTransfer(qualityNotificationMessage, receiverEdcUrl, senderEdcUrl);

//THEN
verify(edcProperties).getApiAuthKey();
verify(edcService).getCatalog(anyString(), anyString(), any());
verify(edcService).initializeContractNegotiation(anyString(), any(), anyString(), any());
verify(endpointDataReferenceCache, times(2)).get(anyString());
verify(objectMapper).writeValueAsString(any());
verify(httpCallService).getUrl(any(), any(), any());
}

@Test
void test_startEDCTransfer_throws_BadRequestException() throws IOException {
//GIVEN
String receiverEdcUrl = "https://example.com/receiver-edcUrl";
String senderEdcUrl = "https://example.com/sender-edcUrl";

QualityNotificationMessage qualityNotificationMessage = NotificationTestDataFactory
.createNotificationTestData(QualityNotificationType.INVESTIGATION);

when(edcProperties.getApiAuthKey()).thenReturn("x-api-key");

Catalog catalog = Catalog.Builder.newInstance().datasets(Collections.emptyList()).build();
when(edcService.getCatalog(anyString(), anyString(), any())).thenReturn(catalog);

//WHEN
BadRequestException badRequestException = assertThrows(
BadRequestException.class,
() -> investigationsEDCFacade.startEDCTransfer(qualityNotificationMessage, receiverEdcUrl, senderEdcUrl));

//THEN
verify(edcProperties).getApiAuthKey();
verify(edcService).getCatalog(anyString(), anyString(), any());
assertEquals("The dataset from the catalog is empty.", badRequestException.getMessage());
}

@Test
void test_startEDCTransfer_throws_BadRequestException_when_catalogItem_isEmpty() throws IOException {
//GIVEN
String receiverEdcUrl = "https://example.com/receiver-edcUrl";
String senderEdcUrl = "https://example.com/sender-edcUrl";

QualityNotificationMessage qualityNotificationMessage = NotificationTestDataFactory
.createNotificationTestData(QualityNotificationType.INVESTIGATION);

when(edcProperties.getApiAuthKey()).thenReturn("x-api-key");

Dataset.Builder datasetBuilder = Dataset.Builder.newInstance()
.property("https://w3id.org/edc/v0.0.1/ns/notificationtype", "invalidNotificationType")
.property("https://w3id.org/edc/v0.0.1/ns/notificationmethod", "invalidNotificationMethod")
.property("https://w3id.org/edc/v0.0.1/ns/id", "id");

Catalog catalog = CatalogTestDataFactory.createCatalogTestData(datasetBuilder);
when(edcService.getCatalog(anyString(), anyString(), any())).thenReturn(catalog);

//WHEN
BadRequestException badRequestException = assertThrows(BadRequestException.class,
() -> investigationsEDCFacade.startEDCTransfer(qualityNotificationMessage, receiverEdcUrl, senderEdcUrl));

//THEN
verify(edcProperties).getApiAuthKey();
verify(edcService).getCatalog(anyString(), anyString(), any());
assertEquals("No Catalog Item in catalog found.", badRequestException.getMessage());

}

@Test
void test_startEDCTransfer_throws_BadRequestException_when_IOException_is_thrown() throws IOException {
//GIVEN
String receiverEdcUrl = "https://example.com/receiver-edcUrl";
String senderEdcUrl = "https://example.com/sender-edcUrl";

QualityNotificationMessage qualityNotificationMessage = NotificationTestDataFactory
.createNotificationTestData(QualityNotificationType.INVESTIGATION);

when(edcProperties.getApiAuthKey()).thenReturn("x-api-key");

when(edcService.getCatalog(anyString(), anyString(), any())).thenThrow(IOException.class);

//WHEN
BadRequestException badRequestException = assertThrows(BadRequestException.class,
() -> investigationsEDCFacade.startEDCTransfer(qualityNotificationMessage, receiverEdcUrl, senderEdcUrl));

//THEN
verify(edcProperties).getApiAuthKey();
verify(edcService).getCatalog(anyString(), anyString(), any());
assertEquals("EDC Data Transfer fail.", badRequestException.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,26 @@

import java.util.Collections;
import java.util.List;
import java.util.Map;

public class CatalogTestDataFactory {

public static Catalog createCatalogTestData() {
return createCatalogTestData(Collections.emptyMap());
}

public static Catalog createCatalogTestData(Map<String, Object> properties) {

OrConstraint orConstraint = OrConstraint.Builder.newInstance().constraint(AtomicConstraint.Builder.newInstance()
.operator(Operator.EQ)
.leftExpression(new LiteralExpression("idsc:PURPOSE"))
.rightExpression(new LiteralExpression("ID 3.0 Trace"))
.build()).build();

Permission permission = Permission.Builder.newInstance()
.action(Action.Builder.newInstance()
.type("USE").build())
.constraints(List.of(AtomicConstraint.Builder.newInstance()
.operator(Operator.EQ)
.leftExpression(new LiteralExpression("idsc:PURPOSE"))
.rightExpression(new LiteralExpression("ID 3.0 Trace"))
.build())).build();
.constraints(List.of(orConstraint)).build();
Policy policy = Policy.Builder.newInstance().permission(permission).build();

DataService dataService = DataService.Builder.newInstance()
Expand All @@ -53,6 +61,29 @@ public static Catalog createCatalogTestData() {
.property("https://w3id.org/edc/v0.0.1/ns/id", "id")
.build();

return Catalog.Builder.newInstance().dataset(dataset).properties(properties).build();
}

public static Catalog createCatalogTestData(Dataset.Builder datasetBuilder) {
Permission permission = Permission.Builder.newInstance()
.action(Action.Builder.newInstance()
.type("USE").build())
.constraints(List.of(AtomicConstraint.Builder.newInstance()
.operator(Operator.EQ)
.leftExpression(new LiteralExpression("idsc:PURPOSE"))
.rightExpression(new LiteralExpression("ID 3.0 Trace"))
.build())).build();
Policy policy = Policy.Builder.newInstance().permission(permission).build();

DataService dataService = DataService.Builder.newInstance()
.build();
Distribution distribution = Distribution.Builder.newInstance().format("format")
.dataService(dataService).build();
Dataset dataset = datasetBuilder
.offer("123", policy)
.distribution(distribution)
.build();

return Catalog.Builder.newInstance().dataset(dataset).properties(Collections.emptyMap()).build();
}

Expand Down