diff --git a/mxd/assets/apache-jmeter-ui.png b/mxd/assets/apache-jmeter-ui.png new file mode 100644 index 00000000..d3ead514 Binary files /dev/null and b/mxd/assets/apache-jmeter-ui.png differ diff --git a/mxd/performance-tests/MXD_Performance_Test.jmx b/mxd/performance-tests/MXD_Performance_Test.jmx new file mode 100644 index 00000000..894b850a --- /dev/null +++ b/mxd/performance-tests/MXD_Performance_Test.jmx @@ -0,0 +1,906 @@ + + + + + false + false + + + + PROVIDER_MANAGEMENT_URL + ${__P(PROVIDER_MANAGEMENT_URL, http://localhost/alice/management)} + = + + + CONSUMER_MANAGEMENT_URL + ${__P(CONSUMER_MANAGEMENT_URL, http://localhost/bob/management)} + = + + + PROVIDER_PROTOCOL_URL + = + ${__P(PROVIDER_PROTOCOL_URL, http://alice-controlplane:8084/api/v1/dsp)} + + + CONSUMER_PROTOCOL_URL + = + ${__P(CONSUMER_PROTOCOL_URL, http://bob-controlplane:8084/api/v1/dsp)} + + + PROVIDER_ID + = + ${__P(PROVIDER_ID, BPNL000000000001)} + + + CONSUMER_ID + = + ${__P(CONSUMER_ID, BPNL000000000002)} + + + BACKEND_SERVICE + = + ${__P(BACKEND_SERVICE, https://requestbin.myworkato.com/1qykac61)} + + + EDC_NAMESPACE + = + ${__P(EDC_NAMESPACE, https://w3id.org/edc/v0.0.1/ns/)} + + + PROVIDER_API_KEY + ${__P(PROVIDER_API_KEY, password)} + = + + + CONSUMER_API_KEY + ${__P(CONSUMER_API_KEY, password)} + = + + + MAX_NEGOTIATION_POLL_COUNT + ${__P(MAX_NEGOTIATION_POLL_COUNT, 10)} + = + + + MAX_TRANSFER_POLL_COUNT + ${__P(MAX_TRANSFER_POLL_COUNT, 10)} + = + + + LOOP_COUNT + ${__P(LOOP_COUNT, 10)} + = + + + + false + + + + + ${LOOP_COUNT} + false + + 1 + + false + ${__P(testduration,)} + + startnextloop + false + true + + + + + NEGOTIATION_ID + NEGOTIATION_STATE + TRANSFER_ID + TRANSFER_STATE + + + + + + + + + + true + Local Variables to be reset after each loop + + + + 100 + + 1 + ID + + false + + + + true + + + + false + { + "@context": {}, + "asset": { + "@type": "Asset", + "@id": "${ID}", + "properties": { + "description": "Product EDC Demo Asset" + } + }, + "dataAddress": { + "@type": "DataAddress", + "type": "HttpData", + "baseUrl": "https://jsonplaceholder.typicode.com/todos/1" + } +} + = + + + + ${PROVIDER_MANAGEMENT_URL}/v2/assets + POST + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${PROVIDER_API_KEY} + + + Content-Type + application/json + + + + + + + 200 + 409 + + + Assertion.response_code + true + 40 + + + + + true + + + + false + { + "@context": { + "odrl": "http://www.w3.org/ns/odrl/2/" + }, + "@type": "PolicyDefinitionRequestDto", + "@id": "${ID}", + "policy": { + "@type": "Policy", + "odrl:permission" : [{ + "odrl:action" : "USE", + "odrl:constraint" : { + "@type": "LogicalConstraint", + "odrl:or" : [{ + "@type" : "Constraint", + "odrl:leftOperand" : "BusinessPartnerNumber", + "odrl:operator" : { + "@id": "odrl:eq" + }, + "odrl:rightOperand" : "${CONSUMER_ID}" + }] + } + }] + } +} + = + + + + ${PROVIDER_MANAGEMENT_URL}/v2/policydefinitions + POST + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${PROVIDER_API_KEY} + + + Content-Type + application/json + + + + + + + 200 + 409 + + + Assertion.response_code + true + 40 + + + + + true + + + + false + { + "@context": {}, + "@id": "${ID}", + "@type": "ContractDefinition", + "accessPolicyId": "${ID}", + "contractPolicyId": "${ID}", + "assetsSelector" : { + "@type" : "CriterionDto", + "operandLeft": "${EDC_NAMESPACE}id", + "operator": "=", + "operandRight": "${ID}" + } +} + = + + + + ${PROVIDER_MANAGEMENT_URL}/v2/contractdefinitions + POST + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${PROVIDER_API_KEY} + + + Content-Type + application/json + + + + + + + 200 + 409 + + + Assertion.response_code + true + 40 + + + + + true + + + + false + { + "@context": { + "edc": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@type": "CatalogRequest", + "counterPartyAddress": "${PROVIDER_PROTOCOL_URL}", + "protocol": "dataspace-protocol-http", + "querySpec": { + "offset": 0, + "limit": 50 + } +} + = + + + + ${CONSUMER_MANAGEMENT_URL}/v2/catalog/request + POST + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${CONSUMER_API_KEY} + + + Content-Type + application/json + + + + + + + true + + + + false + { + "@context": { + "odrl": "http://www.w3.org/ns/odrl/2/" + }, + "@type": "NegotiationInitiateRequestDto", + "connectorAddress": "${PROVIDER_PROTOCOL_URL}", + "protocol": "dataspace-protocol-http", + "connectorId": "${PROVIDER_ID}", + "providerId": "${PROVIDER_ID}", + "offer": { + "offerId": "MQ==:MQ==:ZDM4Nzk3NmUtZjA0Ny00ZmNjLWFhNWItYjQwYmVkMDBhZGYy", + "assetId": "${ID}", + "policy": { + "@type": "odrl:Set", + "odrl:permission": { + "odrl:target": "${ID}", + "odrl:action": { + "odrl:type": "USE" + }, + "odrl:constraint": { + "odrl:or": { + "odrl:leftOperand": "BusinessPartnerNumber", + "odrl:operator": { + "@id": "odrl:eq" + }, + "odrl:rightOperand": "${CONSUMER_ID}" + } + } + }, + "odrl:prohibition": [], + "odrl:obligation": [], + "odrl:target": "${ID}" + } + } +} + = + + + + ${CONSUMER_MANAGEMENT_URL}/v2/contractnegotiations + POST + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${CONSUMER_API_KEY} + + + Content-Type + application/json + + + + + + NEGOTIATION_ID + $['@id'] + 1 + + + + + true + false + + + + ${__jexl3("${NEGOTIATION_STATE}" != "FINALIZED" && +${__jm__Negotiation_State_Loop__idx} < ${MAX_NEGOTIATION_POLL_COUNT})} + Loop while Negotiation State is FINALIZED + + + + 500 + + + + false + + + + ${CONSUMER_MANAGEMENT_URL}/v2/contractnegotiations/${NEGOTIATION_ID}/state + GET + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${CONSUMER_API_KEY} + + + Content-Type + application/json + + + + + + NEGOTIATION_STATE + $['edc:state'] + + + + + + + groovy + + + true + var currentState = vars.get("NEGOTIATION_STATE"); + +if(!"FINALIZED".equals( currentState)) { + SampleResult.setSuccessful(false); + SampleResult.setResponseData("Negotiation State is not 'FINALIZED' after ${vars.get('MAX_NEGOTIATION_POLL_COUNT')} attempts. Current State: ${currentState}"); +} + + + + + + false + + + + ${CONSUMER_MANAGEMENT_URL}/v2/contractnegotiations/${NEGOTIATION_ID} + GET + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${CONSUMER_API_KEY} + + + Content-Type + application/json + + + + + + CONTRACT_AGREEMENT_ID + $['edc:contractAgreementId'] + + + + + + true + + + + false + { + "@context": { + "odrl": "http://www.w3.org/ns/odrl/2/" + }, + "assetId": "${ID}", + "connectorAddress": "${PROVIDER_PROTOCOL_URL}", + "connectorId": "${PROVIDER_ID}", + "contractId": "${CONTRACT_AGREEMENT_ID}", + "dataDestination": { + "type": "HttpProxy" + }, + "privateProperties": { + "receiverHttpEndpoint": "${BACKEND_SERVICE}" + }, + "protocol": "dataspace-protocol-http", + "transferType": { + "contentType": "application/octet-stream", + "isFinite": true + } +} + = + + + + ${CONSUMER_MANAGEMENT_URL}/v2/transferprocesses + POST + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${CONSUMER_API_KEY} + + + Content-Type + application/json + + + + + + TRANSFER_ID + $['@id'] + 1 + + + + + true + false + + + + ${__jexl3("${TRANSFER_STATE}" != "STARTED" && +${__jm__Transfer_State_Loop__idx} < ${MAX_TRANSFER_POLL_COUNT})} + Loop while Transfer State is STARTED + + + + 500 + + + + false + + + + ${CONSUMER_MANAGEMENT_URL}/v2/transferprocesses/${TRANSFER_ID}/state + GET + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${CONSUMER_API_KEY} + + + Content-Type + application/json + + + + + + TRANSFER_STATE + $['edc:state'] + + + + + + + groovy + + + true + var currentState = vars.get("TRANSFER_STATE"); + +if(!"STARTED".equals( currentState)) { + SampleResult.setSuccessful(false); + SampleResult.setResponseData("Transfer State is not 'STARTED' after ${vars.get('MAX_TRANSFER_POLL_COUNT')} attempts. Current State: ${currentState}"); +} + + + + + + false + + + + ${PROVIDER_MANAGEMENT_URL}/v2/contractdefinitions/${ID} + DELETE + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${PROVIDER_API_KEY} + + + Content-Type + application/json + + + + + + + false + + + + ${PROVIDER_MANAGEMENT_URL}/v2/policydefinitions/${ID} + DELETE + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${PROVIDER_API_KEY} + + + Content-Type + application/json + + + + + + + false + + + + ${PROVIDER_MANAGEMENT_URL}/v2/assets/${ID} + DELETE + true + false + true + false + false + false + false + 6 + false + 0 + + + + + + X-Api-Key + ${PROVIDER_API_KEY} + + + Content-Type + application/json + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + + + diff --git a/mxd/performance-tests/README.md b/mxd/performance-tests/README.md new file mode 100644 index 00000000..ee1eae0b --- /dev/null +++ b/mxd/performance-tests/README.md @@ -0,0 +1,52 @@ +# Tractus-X EDC Performance Test + +## 1. Prerequisites +- Download and Install [Apache JMeter](https://jmeter.apache.org/download_jmeter.cgi). +- Add JMETER_HOME/bin to the environment path. [Optional] +- Deploy Tractusx EDC connectors. If you don't have, you can deploy MXD. + +## 2. How to run +- Update connectors properties in the file [connector.properties](connector.properties). +- Run Following command. +```shell +jmeter -n -t MXD_Performance_Test.jmx -l report.jtl -q connector.properties -e -o report +``` + +> It will create a raw `report.jtl` file which will have all the results. It will also generate a nice html report in `report` directory at the end of the performance test. + +## 3. Update the JMeter Script +- Open the script: +```shell +jmeter -t MXD_Performance_Test.jmx +``` +- JMeter window will open like this. +![apache-jmeter-ui.png](../assets/apache-jmeter-ui.png) +- Update the components as per your requirements and save it. + +## Properties Configuration +JMeter Script can be configured via changing properties in the file [connector.properties](connector.properties) + +Following table explains the properties in details. + +| Property | Default Value | Detail | +|----------------------------|-------------------------------------------|----------------------------------------------------------------------------------------------------| +| PROVIDER_MANAGEMENT_URL | http://localhost/alice/management | Provider Data Management URL | +| CONSUMER_MANAGEMENT_URL | http://localhost/bob/management | Consumer Data Management URL | +| PROVIDER_PROTOCOL_URL | http://alice-controlplane:8084/api/v1/dsp | Provider DSP Protocol URL | +| CONSUMER_PROTOCOL_URL | http://bob-controlplane:8084/api/v1/dsp | Consumer DSP Protocol URL | +| PROVIDER_ID | BPNL000000000001 | Provider BPN Number | +| CONSUMER_ID | BPNL000000000002 | Consumer BPN Number | +| BACKEND_SERVICE | http://backend:8080 | Consumer Backend Service Url to receive assets data | +| EDC_NAMESPACE | https://w3id.org/edc/v0.0.1/ns/ | EDC Namespace | +| PROVIDER_API_KEY | password | Provider Data Management API Key | +| CONSUMER_API_KEY | password | Consumer Data Management API Key | +| MAX_NEGOTIATION_POLL_COUNT | 10 | Maximum no of time to poll for negotiation state | +| MAX_TRANSFER_POLL_COUNT | 10 | Maximum no of time to poll for transfer state | +| LOOP_COUNT | 10 | No of time to run the test. This can be increased to a significantly large number like 1M, 5M etc. | + + +## 5. Resources +- [JMeter Getting Started](https://jmeter.apache.org/usermanual/get-started.html) +- [JMeter Component Reference](https://jmeter.apache.org/usermanual/component_reference.html) +- [JMeter Functions Reference](https://jmeter.apache.org/usermanual/functions.html) +- [JMeter Generating Report](https://jmeter.apache.org/usermanual/generating-dashboard.html) diff --git a/mxd/performance-tests/connector.properties b/mxd/performance-tests/connector.properties new file mode 100644 index 00000000..9bef88ba --- /dev/null +++ b/mxd/performance-tests/connector.properties @@ -0,0 +1,13 @@ +PROVIDER_MANAGEMENT_URL=http://localhost/alice/management +CONSUMER_MANAGEMENT_URL=http://localhost/bob/management +PROVIDER_PROTOCOL_URL=http://alice-controlplane:8084/api/v1/dsp +CONSUMER_PROTOCOL_URL=http://bob-controlplane:8084/api/v1/dsp +PROVIDER_ID=BPNL000000000001 +CONSUMER_ID=BPNL000000000002 +BACKEND_SERVICE=http://backend:8080 +EDC_NAMESPACE=https://w3id.org/edc/v0.0.1/ns/ +PROVIDER_API_KEY=password +CONSUMER_API_KEY=password +MAX_NEGOTIATION_POLL_COUNT=10 +MAX_TRANSFER_POLL_COUNT=10 +LOOP_COUNT=10