-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add e2e test for double encoding of query params
- Loading branch information
Showing
4 changed files
with
228 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
213 changes: 213 additions & 0 deletions
213
tests/src/test/java/de/sovity/edc/e2e/DataSourceQueryParamsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
/* | ||
* Copyright (c) 2024 sovity GmbH | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Apache License, Version 2.0 which is available at | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Contributors: | ||
* sovity GmbH - init | ||
*/ | ||
|
||
package de.sovity.edc.e2e; | ||
|
||
import de.sovity.edc.client.EdcClient; | ||
import de.sovity.edc.client.gen.model.ContractDefinitionRequest; | ||
import de.sovity.edc.client.gen.model.ContractNegotiationRequest; | ||
import de.sovity.edc.client.gen.model.ContractNegotiationSimplifiedState; | ||
import de.sovity.edc.client.gen.model.InitiateTransferRequest; | ||
import de.sovity.edc.client.gen.model.PolicyDefinitionCreateRequest; | ||
import de.sovity.edc.client.gen.model.UiAssetCreateRequest; | ||
import de.sovity.edc.client.gen.model.UiContractNegotiation; | ||
import de.sovity.edc.client.gen.model.UiContractOffer; | ||
import de.sovity.edc.client.gen.model.UiCriterion; | ||
import de.sovity.edc.client.gen.model.UiCriterionLiteral; | ||
import de.sovity.edc.client.gen.model.UiCriterionLiteralType; | ||
import de.sovity.edc.client.gen.model.UiCriterionOperator; | ||
import de.sovity.edc.client.gen.model.UiDataOffer; | ||
import de.sovity.edc.client.gen.model.UiPolicyCreateRequest; | ||
import de.sovity.edc.extension.e2e.connector.ConnectorRemote; | ||
import de.sovity.edc.extension.e2e.connector.MockDataAddressRemote; | ||
import de.sovity.edc.extension.e2e.db.TestDatabase; | ||
import de.sovity.edc.extension.e2e.db.TestDatabaseFactory; | ||
import de.sovity.edc.utils.jsonld.vocab.Prop; | ||
import org.awaitility.Awaitility; | ||
import org.eclipse.edc.junit.extensions.EdcExtension; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.RegisterExtension; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import static de.sovity.edc.extension.e2e.connector.DataTransferTestUtil.validateDataTransferred; | ||
import static de.sovity.edc.extension.e2e.connector.config.ConnectorConfigFactory.forTestDatabase; | ||
import static de.sovity.edc.extension.e2e.connector.config.ConnectorRemoteConfigFactory.fromConnectorConfig; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
class DataSourceQueryParamsTest { | ||
|
||
private static final String PROVIDER_PARTICIPANT_ID = "provider"; | ||
private static final String CONSUMER_PARTICIPANT_ID = "consumer"; | ||
|
||
@RegisterExtension | ||
static EdcExtension providerEdcContext = new EdcExtension(); | ||
@RegisterExtension | ||
static EdcExtension consumerEdcContext = new EdcExtension(); | ||
|
||
@RegisterExtension | ||
static final TestDatabase PROVIDER_DATABASE = TestDatabaseFactory.getTestDatabase(1); | ||
@RegisterExtension | ||
static final TestDatabase CONSUMER_DATABASE = TestDatabaseFactory.getTestDatabase(2); | ||
|
||
private ConnectorRemote providerConnector; | ||
private ConnectorRemote consumerConnector; | ||
|
||
private EdcClient providerClient; | ||
private EdcClient consumerClient; | ||
private MockDataAddressRemote dataAddress; | ||
private final String dateParam = "since=2023-10-13T00:00:00.000Z"; | ||
private final String encodedDateParam = "since=2023-10-13T00%3A00%3A00.000Z"; | ||
private final String doubleEncodedDateParam = "since=2023-10-13T00%253A00%253A00.000Z"; | ||
private final String dataOfferId = "my-data-offer-2023-11"; | ||
|
||
@BeforeEach | ||
void setup() { | ||
// set up provider EDC + Client | ||
var providerConfig = forTestDatabase(PROVIDER_PARTICIPANT_ID, 21000, PROVIDER_DATABASE); | ||
providerEdcContext.setConfiguration(providerConfig.getProperties()); | ||
providerConnector = new ConnectorRemote(fromConnectorConfig(providerConfig)); | ||
|
||
providerClient = EdcClient.builder() | ||
.managementApiUrl(providerConfig.getManagementEndpoint().getUri().toString()) | ||
.managementApiKey(providerConfig.getProperties().get("edc.api.auth.key")) | ||
.build(); | ||
|
||
// set up consumer EDC + Client | ||
var consumerConfig = forTestDatabase(CONSUMER_PARTICIPANT_ID, 23000, CONSUMER_DATABASE); | ||
consumerEdcContext.setConfiguration(consumerConfig.getProperties()); | ||
consumerConnector = new ConnectorRemote(fromConnectorConfig(consumerConfig)); | ||
|
||
consumerClient = EdcClient.builder() | ||
.managementApiUrl(consumerConfig.getManagementEndpoint().getUri().toString()) | ||
.managementApiKey(consumerConfig.getProperties().get("edc.api.auth.key")) | ||
.build(); | ||
|
||
// We use the provider EDC as data sink / data source (it has the test-backend-controller extension) | ||
dataAddress = new MockDataAddressRemote(providerConnector.getConfig().getDefaultEndpoint()); | ||
} | ||
|
||
@Test | ||
void testDirectQuerying() { | ||
// arrange | ||
var paramUrl = String.format("%s?{k}={v}", dataAddress.getDataSourceQueryParamsUrl()); | ||
var splitParam = dateParam.split("="); | ||
var paramKey = splitParam[0]; | ||
var paramValue = splitParam[1]; | ||
|
||
// act | ||
// assert | ||
validateDataTransferred(paramUrl, encodedDateParam, paramValue, paramKey); | ||
} | ||
|
||
/** | ||
* This test will fail as soon as the handling of query parameters is fixed in the EDC project | ||
*/ | ||
@Test | ||
void testQueryParamsDoubleEncoded() { | ||
// arrange | ||
createPolicy(); | ||
createAsset(); | ||
createContractDefinition(); | ||
|
||
// act | ||
var dataOffers = consumerClient.uiApi().getCatalogPageDataOffers(getProtocolEndpoint(providerConnector)); | ||
var negotiation = initiateNegotiation(dataOffers.get(0), dataOffers.get(0).getContractOffers().get(0)); | ||
negotiation = awaitNegotiationDone(negotiation.getContractNegotiationId()); | ||
initiateTransfer(negotiation); | ||
|
||
// assert | ||
validateDataTransferred(dataAddress.getDataSinkSpyUrl(), doubleEncodedDateParam); | ||
} | ||
|
||
private void createAsset() { | ||
var asset = UiAssetCreateRequest.builder() | ||
.id(dataOfferId) | ||
.title("My Data Offer") | ||
.dataAddressProperties(Map.of( | ||
Prop.Edc.TYPE, "HttpData", | ||
Prop.Edc.METHOD, "GET", | ||
Prop.Edc.BASE_URL, dataAddress.getDataSourceQueryParamsUrl(), | ||
"https://w3id.org/edc/v0.0.1/ns/queryParams", encodedDateParam | ||
)) | ||
.build(); | ||
|
||
providerClient.uiApi().createAsset(asset); | ||
} | ||
|
||
private void createPolicy() { | ||
var policyDefinition = PolicyDefinitionCreateRequest.builder() | ||
.policyDefinitionId(dataOfferId) | ||
.policy(UiPolicyCreateRequest.builder() | ||
.constraints(List.of()) | ||
.build()) | ||
.build(); | ||
|
||
providerClient.uiApi().createPolicyDefinition(policyDefinition); | ||
} | ||
|
||
private void createContractDefinition() { | ||
var contractDefinition = ContractDefinitionRequest.builder() | ||
.contractDefinitionId(dataOfferId) | ||
.accessPolicyId(dataOfferId) | ||
.contractPolicyId(dataOfferId) | ||
.assetSelector(List.of(UiCriterion.builder() | ||
.operandLeft(Prop.Edc.ID) | ||
.operator(UiCriterionOperator.EQ) | ||
.operandRight(UiCriterionLiteral.builder() | ||
.type(UiCriterionLiteralType.VALUE) | ||
.value(dataOfferId) | ||
.build()) | ||
.build())) | ||
.build(); | ||
|
||
providerClient.uiApi().createContractDefinition(contractDefinition); | ||
} | ||
|
||
private UiContractNegotiation initiateNegotiation(UiDataOffer dataOffer, UiContractOffer contractOffer) { | ||
var negotiationRequest = ContractNegotiationRequest.builder() | ||
.counterPartyAddress(dataOffer.getEndpoint()) | ||
.counterPartyParticipantId(dataOffer.getParticipantId()) | ||
.assetId(dataOffer.getAsset().getAssetId()) | ||
.contractOfferId(contractOffer.getContractOfferId()) | ||
.policyJsonLd(contractOffer.getPolicy().getPolicyJsonLd()) | ||
.build(); | ||
|
||
return consumerClient.uiApi().initiateContractNegotiation(negotiationRequest); | ||
} | ||
|
||
private UiContractNegotiation awaitNegotiationDone(String negotiationId) { | ||
var negotiation = Awaitility.await().atMost(consumerConnector.timeout).until( | ||
() -> consumerClient.uiApi().getContractNegotiation(negotiationId), | ||
it -> it.getState().getSimplifiedState() != ContractNegotiationSimplifiedState.IN_PROGRESS | ||
); | ||
|
||
assertThat(negotiation.getState().getSimplifiedState()).isEqualTo(ContractNegotiationSimplifiedState.AGREED); | ||
return negotiation; | ||
} | ||
|
||
private void initiateTransfer(UiContractNegotiation negotiation) { | ||
var contractAgreementId = negotiation.getContractAgreementId(); | ||
var transferRequest = InitiateTransferRequest.builder() | ||
.contractAgreementId(contractAgreementId) | ||
.dataSinkProperties(dataAddress.getDataSinkProperties()) | ||
.build(); | ||
consumerClient.uiApi().initiateTransfer(transferRequest); | ||
} | ||
|
||
private String getProtocolEndpoint(ConnectorRemote connector) { | ||
return connector.getConfig().getProtocolEndpoint().getUri().toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters