diff --git a/CHANGELOG.md b/CHANGELOG.md index 4909d654fe..6b4e047183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,17 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 _**For better traceability add the corresponding GitHub issue number in each changelog entry, please.**_ ## [Unreleased] +### Changed +- IRS now supports Asset Administration Shell v3.1 - adjusted lookup shells endpoint changes (assetIds query param is encoded). #359 +- ### Added - Extended EdcPolicyDefinitionService to check if a policy in the edc exists ## [4.8.0] - 2024-03-18 ### Changed - Improved maintainability in EdcSubmodelClientImpl by reduced method visibility and better naming (in context of #448). -- EdcPolicyDefinitionService, EdcContractDefinitionService and EdcAssetService return throw AlreadyExist exceptions when Conflict is returned from - EDC +- EdcPolicyDefinitionService, EdcContractDefinitionService and EdcAssetService throw AlreadyExist exceptions when + conflict is returned from EDC - Added AssetAdministrationShellDescriptor specificAssetIds support for externalSubjectId required for data provisioning - Registering a job - aspects array is now accepting full urn of aspect model instead of name only, eg. 'urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt' instead 'SingleLevelBomAsBuilt'. #439 - Changed the version of irs-registry-client from 1.6.0-SNAPSHOT to 1.6.0 +- Policies can now be registered for certain bpnls. #199 + ## Fixed - Fixed missing timeouts including configuration. #448 @@ -191,7 +196,7 @@ _**For better traceability add the corresponding GitHub issue number in each cha - Added role "admin_irs" again ### Changed -- Deprecated query parameter 'jobStates' was removed from GET {{IRS_HOST}}/irs/jobs endpoint +- Deprecated query parameter 'jobStates' was removed from GET {{IRS_HOST}}/irs/jobs endpoint. TRI-996 - Moved OAuth2 JWT token claim to configuration. The fields can be configured with `oauth.resourceClaim`, `oauth.irsNamespace`, `oauth.roles`. - ESS - Added Tombstone to ESS investigation in case required aspect models "PartAsPlanned" or "PartSiteInformationAsPlanned" are missing diff --git a/DEPENDENCIES b/DEPENDENCIES index d9c7829148..422feee65b 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -125,9 +125,9 @@ maven/mavencentral/io.github.resilience4j/resilience4j-retry/2.1.0, Apache-2.0, maven/mavencentral/io.github.resilience4j/resilience4j-spring-boot3/2.1.0, Apache-2.0, approved, #10913 maven/mavencentral/io.github.resilience4j/resilience4j-spring6/2.1.0, Apache-2.0, approved, #10915 maven/mavencentral/io.github.resilience4j/resilience4j-timelimiter/2.1.0, Apache-2.0, approved, #10166 -maven/mavencentral/io.micrometer/micrometer-commons/1.11.9, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #9243 -maven/mavencentral/io.micrometer/micrometer-core/1.11.9, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #9238 -maven/mavencentral/io.micrometer/micrometer-observation/1.11.9, Apache-2.0, approved, #9242 +maven/mavencentral/io.micrometer/micrometer-commons/1.11.10, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #9243 +maven/mavencentral/io.micrometer/micrometer-core/1.11.10, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #9238 +maven/mavencentral/io.micrometer/micrometer-observation/1.11.10, Apache-2.0, approved, #9242 maven/mavencentral/io.micrometer/micrometer-registry-prometheus/1.11.4, Apache-2.0, approved, #9805 maven/mavencentral/io.minio/minio/8.5.6, Apache-2.0, approved, #9097 maven/mavencentral/io.netty.incubator/netty-incubator-transport-classes-io_uring/0.0.21.Final, Apache-2.0, approved, #9622 @@ -174,7 +174,7 @@ maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.15, Apache maven/mavencentral/io.swagger.core.v3/swagger-annotations/2.2.16, Apache-2.0, approved, #11362 maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.15, Apache-2.0, approved, #5929 maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.15, Apache-2.0, approved, #5919 -maven/mavencentral/jakarta.activation/jakarta.activation-api/2.1.2, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf +maven/mavencentral/jakarta.activation/jakarta.activation-api/2.1.3, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf maven/mavencentral/jakarta.annotation/jakarta.annotation-api/2.1.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.ca maven/mavencentral/jakarta.inject/jakarta.inject-api/2.0.1, Apache-2.0, approved, ee4j.cdi maven/mavencentral/jakarta.json/jakarta.json-api/2.1.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jsonp @@ -183,7 +183,7 @@ maven/mavencentral/jakarta.transaction/jakarta.transaction-api/2.0.0, EPL-2.0 OR maven/mavencentral/jakarta.transaction/jakarta.transaction-api/2.0.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jta maven/mavencentral/jakarta.validation/jakarta.validation-api/3.0.2, Apache-2.0, approved, ee4j.validation maven/mavencentral/jakarta.ws.rs/jakarta.ws.rs-api/3.1.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.rest -maven/mavencentral/jakarta.xml.bind/jakarta.xml.bind-api/4.0.1, BSD-3-Clause, approved, ee4j.jaxb +maven/mavencentral/jakarta.xml.bind/jakarta.xml.bind-api/4.0.2, BSD-3-Clause, approved, ee4j.jaxb maven/mavencentral/javax.jms/javax.jms-api/2.0.1, CDDL-1.1 OR GPL-2.0 WITH Classpath-exception-2.0, approved, #1516 maven/mavencentral/joda-time/joda-time/2.10.2, Apache-2.0, approved, clearlydefined maven/mavencentral/junit/junit/4.13.2, EPL-2.0, approved, CQ23636 @@ -209,9 +209,9 @@ maven/mavencentral/net.sf.saxon/Saxon-HE/10.6, MPL-2.0 AND W3C, approved, #7945 maven/mavencentral/org.apache.commons/commons-compress/1.24.0, Apache-2.0 AND BSD-3-Clause AND bzip2-1.0.6 AND LicenseRef-Public-Domain, approved, #10368 maven/mavencentral/org.apache.commons/commons-lang3/3.12.0, Apache-2.0, approved, clearlydefined maven/mavencentral/org.apache.commons/commons-pool2/2.11.1, Apache-2.0, approved, CQ23795 -maven/mavencentral/org.apache.groovy/groovy-json/4.0.18, Apache-2.0, approved, #7411 -maven/mavencentral/org.apache.groovy/groovy-xml/4.0.18, Apache-2.0, approved, #10179 -maven/mavencentral/org.apache.groovy/groovy/4.0.18, Apache-2.0 AND BSD-3-Clause AND MIT, approved, #1742 +maven/mavencentral/org.apache.groovy/groovy-json/4.0.20, Apache-2.0, approved, #7411 +maven/mavencentral/org.apache.groovy/groovy-xml/4.0.20, Apache-2.0, approved, #10179 +maven/mavencentral/org.apache.groovy/groovy/4.0.20, Apache-2.0 AND BSD-3-Clause AND MIT, approved, #1742 maven/mavencentral/org.apache.httpcomponents/httpclient/4.5.13, Apache-2.0 AND LicenseRef-Public-Domain, approved, CQ23527 maven/mavencentral/org.apache.httpcomponents/httpcore/4.4.16, Apache-2.0, approved, CQ23528 maven/mavencentral/org.apache.httpcomponents/httpmime/4.5.13, Apache-2.0, approved, CQ11718 @@ -426,44 +426,44 @@ maven/mavencentral/org.slf4j/slf4j-api/2.0.12, MIT, approved, #5915 maven/mavencentral/org.springdoc/springdoc-openapi-starter-common/2.2.0, Apache-2.0, approved, clearlydefined maven/mavencentral/org.springdoc/springdoc-openapi-starter-webmvc-api/2.2.0, Apache-2.0, approved, clearlydefined maven/mavencentral/org.springdoc/springdoc-openapi-starter-webmvc-ui/2.2.0, Apache-2.0, approved, clearlydefined -maven/mavencentral/org.springframework.boot/spring-boot-actuator-autoconfigure/3.1.9, Apache-2.0, approved, #9348 -maven/mavencentral/org.springframework.boot/spring-boot-actuator/3.1.9, Apache-2.0, approved, #9342 -maven/mavencentral/org.springframework.boot/spring-boot-autoconfigure/3.1.9, Apache-2.0, approved, #9341 -maven/mavencentral/org.springframework.boot/spring-boot-configuration-metadata/3.1.9, Apache-2.0, approved, #11032 -maven/mavencentral/org.springframework.boot/spring-boot-properties-migrator/3.1.9, Apache-2.0, approved, #10675 -maven/mavencentral/org.springframework.boot/spring-boot-starter-actuator/3.1.9, Apache-2.0, approved, #9344 -maven/mavencentral/org.springframework.boot/spring-boot-starter-aop/3.1.9, Apache-2.0, approved, #9338 -maven/mavencentral/org.springframework.boot/spring-boot-starter-json/3.1.9, Apache-2.0, approved, #9336 -maven/mavencentral/org.springframework.boot/spring-boot-starter-log4j2/3.1.9, Apache-2.0, approved, #8800 -maven/mavencentral/org.springframework.boot/spring-boot-starter-logging/3.1.9, Apache-2.0, approved, #9343 -maven/mavencentral/org.springframework.boot/spring-boot-starter-oauth2-client/3.1.9, Apache-2.0, approved, #8806 -maven/mavencentral/org.springframework.boot/spring-boot-starter-security/3.1.9, Apache-2.0, approved, #9337 -maven/mavencentral/org.springframework.boot/spring-boot-starter-test/3.1.9, Apache-2.0, approved, #9353 -maven/mavencentral/org.springframework.boot/spring-boot-starter-tomcat/3.1.9, Apache-2.0, approved, #9351 -maven/mavencentral/org.springframework.boot/spring-boot-starter-validation/3.1.9, Apache-2.0, approved, #9335 -maven/mavencentral/org.springframework.boot/spring-boot-starter-web/3.1.9, Apache-2.0, approved, #9347 -maven/mavencentral/org.springframework.boot/spring-boot-starter/3.1.9, Apache-2.0, approved, #9349 -maven/mavencentral/org.springframework.boot/spring-boot-test-autoconfigure/3.1.9, Apache-2.0, approved, #9339 -maven/mavencentral/org.springframework.boot/spring-boot-test/3.1.9, Apache-2.0, approved, #9346 -maven/mavencentral/org.springframework.boot/spring-boot/3.1.9, Apache-2.0, approved, #9352 -maven/mavencentral/org.springframework.data/spring-data-commons/3.1.9, Apache-2.0, approved, #8805 -maven/mavencentral/org.springframework.security/spring-security-config/6.1.7, Apache-2.0, approved, #9736 -maven/mavencentral/org.springframework.security/spring-security-core/6.1.7, Apache-2.0, approved, #9801 -maven/mavencentral/org.springframework.security/spring-security-crypto/6.1.7, Apache-2.0 AND ISC, approved, #9735 -maven/mavencentral/org.springframework.security/spring-security-oauth2-client/6.1.7, Apache-2.0, approved, #9740 -maven/mavencentral/org.springframework.security/spring-security-oauth2-core/6.1.7, Apache-2.0, approved, #9741 -maven/mavencentral/org.springframework.security/spring-security-oauth2-jose/6.1.7, Apache-2.0, approved, #9345 -maven/mavencentral/org.springframework.security/spring-security-test/6.1.7, Apache-2.0, approved, #10674 -maven/mavencentral/org.springframework.security/spring-security-web/6.1.7, Apache-2.0, approved, #9800 -maven/mavencentral/org.springframework/spring-aop/6.0.17, Apache-2.0, approved, #5940 -maven/mavencentral/org.springframework/spring-beans/6.0.17, Apache-2.0, approved, #5937 -maven/mavencentral/org.springframework/spring-context/6.0.17, Apache-2.0, approved, #5936 -maven/mavencentral/org.springframework/spring-core/6.0.17, Apache-2.0 AND BSD-3-Clause, approved, #5948 -maven/mavencentral/org.springframework/spring-expression/6.0.17, Apache-2.0, approved, #3284 -maven/mavencentral/org.springframework/spring-jcl/6.0.17, Apache-2.0, approved, #3283 -maven/mavencentral/org.springframework/spring-test/6.0.17, Apache-2.0, approved, #7003 -maven/mavencentral/org.springframework/spring-web/6.0.17, Apache-2.0, approved, #5942 -maven/mavencentral/org.springframework/spring-webmvc/6.0.17, Apache-2.0, approved, #5944 +maven/mavencentral/org.springframework.boot/spring-boot-actuator-autoconfigure/3.1.10, Apache-2.0, approved, #9348 +maven/mavencentral/org.springframework.boot/spring-boot-actuator/3.1.10, Apache-2.0, approved, #9342 +maven/mavencentral/org.springframework.boot/spring-boot-autoconfigure/3.1.10, Apache-2.0, approved, #9341 +maven/mavencentral/org.springframework.boot/spring-boot-configuration-metadata/3.1.10, Apache-2.0, approved, #11032 +maven/mavencentral/org.springframework.boot/spring-boot-properties-migrator/3.1.10, Apache-2.0, approved, #10675 +maven/mavencentral/org.springframework.boot/spring-boot-starter-actuator/3.1.10, Apache-2.0, approved, #9344 +maven/mavencentral/org.springframework.boot/spring-boot-starter-aop/3.1.10, Apache-2.0, approved, #9338 +maven/mavencentral/org.springframework.boot/spring-boot-starter-json/3.1.10, Apache-2.0, approved, #9336 +maven/mavencentral/org.springframework.boot/spring-boot-starter-log4j2/3.1.10, Apache-2.0, approved, #8800 +maven/mavencentral/org.springframework.boot/spring-boot-starter-logging/3.1.10, Apache-2.0, approved, #9343 +maven/mavencentral/org.springframework.boot/spring-boot-starter-oauth2-client/3.1.10, Apache-2.0, approved, #8806 +maven/mavencentral/org.springframework.boot/spring-boot-starter-security/3.1.10, Apache-2.0, approved, #9337 +maven/mavencentral/org.springframework.boot/spring-boot-starter-test/3.1.10, Apache-2.0, approved, #9353 +maven/mavencentral/org.springframework.boot/spring-boot-starter-tomcat/3.1.10, Apache-2.0, approved, #9351 +maven/mavencentral/org.springframework.boot/spring-boot-starter-validation/3.1.10, Apache-2.0, approved, #9335 +maven/mavencentral/org.springframework.boot/spring-boot-starter-web/3.1.10, Apache-2.0, approved, #9347 +maven/mavencentral/org.springframework.boot/spring-boot-starter/3.1.10, Apache-2.0, approved, #9349 +maven/mavencentral/org.springframework.boot/spring-boot-test-autoconfigure/3.1.10, Apache-2.0, approved, #9339 +maven/mavencentral/org.springframework.boot/spring-boot-test/3.1.10, Apache-2.0, approved, #9346 +maven/mavencentral/org.springframework.boot/spring-boot/3.1.10, Apache-2.0, approved, #9352 +maven/mavencentral/org.springframework.data/spring-data-commons/3.1.10, Apache-2.0, approved, #8805 +maven/mavencentral/org.springframework.security/spring-security-config/6.1.8, Apache-2.0, approved, #9736 +maven/mavencentral/org.springframework.security/spring-security-core/6.1.8, Apache-2.0, approved, #9801 +maven/mavencentral/org.springframework.security/spring-security-crypto/6.1.8, Apache-2.0 AND ISC, approved, #9735 +maven/mavencentral/org.springframework.security/spring-security-oauth2-client/6.1.8, Apache-2.0, approved, #9740 +maven/mavencentral/org.springframework.security/spring-security-oauth2-core/6.1.8, Apache-2.0, approved, #9741 +maven/mavencentral/org.springframework.security/spring-security-oauth2-jose/6.1.8, Apache-2.0, approved, #9345 +maven/mavencentral/org.springframework.security/spring-security-test/6.1.8, Apache-2.0, approved, #10674 +maven/mavencentral/org.springframework.security/spring-security-web/6.1.8, Apache-2.0, approved, #9800 +maven/mavencentral/org.springframework/spring-aop/6.0.18, Apache-2.0, approved, #5940 +maven/mavencentral/org.springframework/spring-beans/6.0.18, Apache-2.0, approved, #5937 +maven/mavencentral/org.springframework/spring-context/6.0.18, Apache-2.0, approved, #5936 +maven/mavencentral/org.springframework/spring-core/6.0.18, Apache-2.0 AND BSD-3-Clause, approved, #5948 +maven/mavencentral/org.springframework/spring-expression/6.0.18, Apache-2.0, approved, #3284 +maven/mavencentral/org.springframework/spring-jcl/6.0.18, Apache-2.0, approved, #3283 +maven/mavencentral/org.springframework/spring-test/6.0.18, Apache-2.0, approved, #7003 +maven/mavencentral/org.springframework/spring-web/6.0.18, Apache-2.0, approved, #5942 +maven/mavencentral/org.springframework/spring-webmvc/6.0.18, Apache-2.0, approved, #5944 maven/mavencentral/org.testcontainers/junit-jupiter/1.18.3, MIT, approved, #7941 maven/mavencentral/org.testcontainers/junit-jupiter/1.19.1, MIT, approved, #10344 maven/mavencentral/org.testcontainers/testcontainers/1.18.3, MIT, approved, #7938 diff --git a/charts/irs-helm/templates/configmap-spring-app-config.yaml b/charts/irs-helm/templates/configmap-spring-app-config.yaml index 54180b10d6..7225bd3182 100644 --- a/charts/irs-helm/templates/configmap-spring-app-config.yaml +++ b/charts/irs-helm/templates/configmap-spring-app-config.yaml @@ -161,8 +161,6 @@ data: {{- end }} {{- end }} - apiAllowedBpn: {{ tpl (.Values.bpn | default "") . | quote }} - {{- if .Values.config.content }} {{- tpl (toYaml .Values.config.content) . | nindent 4 }} {{- end }} diff --git a/docs/src/api/irs-api.yaml b/docs/src/api/irs-api.yaml index 1e08bb0b51..406fcf0808 100644 --- a/docs/src/api/irs-api.yaml +++ b/docs/src/api/irs-api.yaml @@ -794,7 +794,15 @@ paths: /irs/policies: get: description: Lists the registered policies that should be accepted in EDC negotiation. - operationId: getAllowedPolicies + operationId: getAllowedPoliciesByBpn + parameters: + - name: bpnls + in: query + required: false + schema: + type: array + items: + type: string responses: "200": content: @@ -823,7 +831,7 @@ paths: $ref: '#/components/schemas/ErrorResponse' description: Authorization refused by server. security: - - api_key: [] + - api_key: [ ] summary: Lists the registered policies that should be accepted in EDC negotiation. tags: - Item Relationship Service @@ -871,16 +879,15 @@ paths: summary: Register a policy that should be accepted in EDC negotiation. tags: - Item Relationship Service - /irs/policies/{policyId}: - delete: - description: Removes a policy that should no longer be accepted in EDC negotiation. - operationId: deleteAllowedPolicy - parameters: - - in: path - name: policyId - required: true - schema: - type: string + put: + description: Updates an existing policy. + operationId: updateAllowedPolicy + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdatePolicyRequest' + required: true responses: "200": description: OK @@ -892,7 +899,7 @@ paths: $ref: '#/components/examples/error-response-400' schema: $ref: '#/components/schemas/ErrorResponse' - description: Policy deletion failed. + description: Policy update failed. "401": content: application/json: @@ -912,25 +919,20 @@ paths: $ref: '#/components/schemas/ErrorResponse' description: Authorization refused by server. security: - - api_key: [] - summary: Removes a policy that should no longer be accepted in EDC negotiation. + - api_key: [ ] + summary: Updates an existing policy. tags: - Item Relationship Service - put: - description: Updates an existing policy with new validUntil value. - operationId: updateAllowedPolicy + /irs/policies/{policyId}: + delete: + description: Removes a policy that should no longer be accepted in EDC negotiation. + operationId: deleteAllowedPolicy parameters: - in: path name: policyId required: true schema: type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UpdatePolicyRequest' - required: true responses: "200": description: OK @@ -942,7 +944,7 @@ paths: $ref: '#/components/examples/error-response-400' schema: $ref: '#/components/schemas/ErrorResponse' - description: Policy update failed. + description: Policy deletion failed. "401": content: application/json: @@ -963,7 +965,7 @@ paths: description: Authorization refused by server. security: - api_key: [] - summary: Updates an existing policy with new validUntil value. + summary: Removes a policy that should no longer be accepted in EDC negotiation. tags: - Item Relationship Service components: @@ -1736,9 +1738,9 @@ components: description: Request to add a policy properties: payload: - type: object - additionalProperties: - $ref: '#/components/schemas/JsonValue' + type: array + items: + $ref: '#/components/schemas/JsonObject' example: payload: '@context': @@ -1758,23 +1760,14 @@ components: '@id': 'odrl:eq' 'odrl:rightOperand': ID 3.1 Trace validUntil: '2025-12-12T23:59:59.999Z' - properties: - empty: - type: boolean - valueType: - type: string - enum: - - 'ARRAY' - - 'OBJECT' - - 'STRING' - - 'NUMBER' - - 'TRUE' - - 'FALSE' - - 'NULL' validUntil: type: string format: date-time description: Timestamp after which the policy will no longer be accepted in negotiations + businessPartnerNumbers: + type: array + items: + type: string required: - payload - validUntil @@ -2237,6 +2230,41 @@ components: items: $ref: '#/components/schemas/Tombstone' maxItems: 2147483647 + JsonObject: + type: object + additionalProperties: false + properties: + valueType: + type: string + enum: + - 'ARRAY' + - 'OBJECT' + - 'STRING' + - 'NUMBER' + - 'TRUE' + - 'FALSE' + - 'NULL' + empty: + type: boolean + example: + payload: + '@context': + odrl: http://www.w3.org/ns/odrl/2/ + '@id': policy-id + policy: + 'odrl:permission': + - 'odrl:action': USE + 'odrl:constraint': + 'odrl:and': + - 'odrl:leftOperand': Membership + 'odrl:operator': + '@id': 'odrl:eq' + 'odrl:rightOperand': active + - 'odrl:leftOperand': PURPOSE + 'odrl:operator': + '@id': 'odrl:eq' + 'odrl:rightOperand': ID 3.1 Trace + validUntil: '2025-12-12T23:59:59.999Z' JsonValue: type: object additionalProperties: false @@ -2938,6 +2966,14 @@ components: additionalProperties: false description: Request to add a policy properties: + businessPartnerNumbers: + type: array + items: + type: string + policiesIds: + type: array + items: + type: string validUntil: type: string format: date-time diff --git a/docs/src/docs/arc42/glossary.adoc b/docs/src/docs/arc42/glossary.adoc index 73e314454f..a1753da1e1 100644 --- a/docs/src/docs/arc42/glossary.adoc +++ b/docs/src/docs/arc42/glossary.adoc @@ -8,6 +8,9 @@ |Aspect Servers (Submodel Endpoints) | | Companies participating in the interorganizational data exchange provides their data over aspect servers. The so called "submodel-descriptors" in the AAS shells are pointing to these AspectServers which provide the data-assets of the participating these companies in Catena-X. |Bill of Materials | BoM | A Bill of Materials is a comprehensive list of materials, components, sub-assemblies, and the quantities of each needed to manufacture or build a product. It serves as a structured document that provides information about the raw materials, parts, and components required for the production process. |Business Partner Number | BPN | A BPN is the unique identifier of a partner within Catena-X +|Business Partner Number Legal Enitity | BPNL | A legal entity is a juridical person or group which has legal rights and duties related to contracts, agreements, obligations etc. The term applies to any kind of organization which was founded under the particular set of law governing the country. +|Business Partner Number Site | BPNS | A site is a delimited geographical area where a legal entity does business (geographical address with geo coordinates). Providing a primary physical address for a site is mandatory. It is possible to specify further physical addresses for this location. P.O. box details are only possible in addition to the physical address. A site has a 1:n relation to addresses, means at least 1 address is necessary and multiple addresses are possible. +|Business Partner Number Address | BPNA | An address is a collection of information to describe a position, e.g. using street names or P.O. boxes as references. In addition an address consists of several postal attributes, e.g. Country, Region (State), District, Postal Code, City. |CatalogItem| | A "CatalogItem" from EDC is a synonym for "Contract Offer". |Contract Offer| | A "Contract Offer" is a synonym for "CatalogItem" from EDC. |Data Space | | Data Spaces are the key concept for a large-scale, cross-border data economy. This is also the vision of the Gaia-X initiative for a data infrastructure in Europe. The International Data Space Association (IDSA) contributes significantly to this with the architectural model, interfaces, and standards. diff --git a/docs/src/uml-diagrams/irs-recursive/use-case-esr-certificate/esr-certificate-sequence-irs.puml b/docs/src/uml-diagrams/irs-recursive/use-case-esr-certificate/esr-certificate-sequence-irs.puml index b5c42b226c..22ec9c174d 100644 --- a/docs/src/uml-diagrams/irs-recursive/use-case-esr-certificate/esr-certificate-sequence-irs.puml +++ b/docs/src/uml-diagrams/irs-recursive/use-case-esr-certificate/esr-certificate-sequence-irs.puml @@ -29,7 +29,7 @@ ref over IRS, DTRegistry, DAPS, "SubmodelServer AssemblyPartRelationship)" end ref loop 100 times - ESRSubServer --> IRS: GET /irs/jobs?jobStates=COMPLETED + ESRSubServer --> IRS: GET /irs/jobs?states=COMPLETED ESRSubServer <-- IRS: jobList alt jobId is in jobList ESRSubServer --> IRS: GET /irs/jobs{jobId} diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java index 5823cff156..0f3664fc39 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java @@ -98,22 +98,22 @@ protected SubmodelDescriptor requestSubmodel(final EdcSubmodelFacade submodelFac log.debug("Using dspEndpoint of subprotocolBody '{}' to get submodel payload", subprotocolBody); return submodelFacade.getSubmodelPayload(dspEndpoint.get(), digitalTwinRegistryEndpoint.getProtocolInformation().getHref(), - extractAssetId(subprotocolBody)); + extractAssetId(subprotocolBody), bpn); } else { log.info("SubprotocolBody does not contain '{}'. Using Discovery Service as fallback.", DSP_ENDPOINT); final List connectorEndpoints = connectorEndpointsService.fetchConnectorEndpoints(bpn); - return getSubmodel(submodelFacade, digitalTwinRegistryEndpoint, connectorEndpoints); + return getSubmodel(submodelFacade, digitalTwinRegistryEndpoint, connectorEndpoints, bpn); } } private SubmodelDescriptor getSubmodel(final EdcSubmodelFacade submodelFacade, final Endpoint digitalTwinRegistryEndpoint, - final List connectorEndpoints) throws EdcClientException { + final List connectorEndpoints, final String bpn) throws EdcClientException { for (final String connectorEndpoint : connectorEndpoints) { try { return submodelFacade.getSubmodelPayload(connectorEndpoint, digitalTwinRegistryEndpoint.getProtocolInformation().getHref(), - extractAssetId(digitalTwinRegistryEndpoint.getProtocolInformation().getSubprotocolBody())); + extractAssetId(digitalTwinRegistryEndpoint.getProtocolInformation().getSubprotocolBody()), bpn); } catch (EdcClientException e) { log.info("EdcClientException while accessing digitalTwinRegistryEndpoint '{}'", connectorEndpoint, e); } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/RegistryConfiguration.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/RegistryConfiguration.java index 7b2d866bd8..936aa6ebbc 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/RegistryConfiguration.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/RegistryConfiguration.java @@ -76,9 +76,9 @@ public DecentralDigitalTwinRegistryService decentralDigitalTwinRegistryService( @Value("${digitalTwinRegistry.lookupShellsTemplate:}") final String lookupShellsTemplate, final EdcConfiguration edcConfiguration) { - final EdcEndpointReferenceRetriever endpointReferenceRetriever = (edcConnectorEndpoint, assetType, assetValue) -> { + final EdcEndpointReferenceRetriever endpointReferenceRetriever = (edcConnectorEndpoint, assetType, assetValue, bpn) -> { try { - return facade.getEndpointReferencesForAsset(edcConnectorEndpoint, assetType, assetValue); + return facade.getEndpointReferencesForAsset(edcConnectorEndpoint, assetType, assetValue, bpn); } catch (EdcClientException e) { throw new EdcRetrieverException(e); } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/controller/mock/MockedNotificationReceiverController.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/controller/mock/MockedNotificationReceiverController.java index a6e6bffabb..4f1eb9410e 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/controller/mock/MockedNotificationReceiverController.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/controller/mock/MockedNotificationReceiverController.java @@ -107,7 +107,7 @@ public void receiveNotification( final EdcNotification edcRequest = edcRequest(notificationId, originalNotificationId, senderEdc, senderBpn, recipientBpn, notificationContent); - final var response = edcSubmodelFacade.sendNotification(recipientUrl, "ess-response-asset", edcRequest); + final var response = edcSubmodelFacade.sendNotification(recipientUrl, "ess-response-asset", edcRequest, recipientBpn); if (!response.deliveredSuccessfully()) { throw new EdcClientException( "EDC Provider did not accept message with notificationId " + notificationId); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java index 3987c12624..ebaa775c83 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java @@ -76,7 +76,7 @@ public void sendEdcNotification(final EdcNotification getBlob(final String sourceBlobName) { return Optional.ofNullable(store.get(sourceBlobName)); } + @Override + public Map getAllBlobs() { + return store; + } + @Override public Collection findBlobByPrefix(final String prefix) { return store.entrySet() diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java index 185d74a8b4..4ff1a14453 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java @@ -20,12 +20,14 @@ package org.eclipse.tractusx.irs; import static com.github.tomakehurst.wiremock.client.WireMock.containing; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.tractusx.irs.WiremockSupport.createEndpointDataReference; +import static org.eclipse.tractusx.irs.WiremockSupport.encodedAssetIds; import static org.eclipse.tractusx.irs.WiremockSupport.randomUUID; import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockSupport.DISCOVERY_FINDER_PATH; import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockSupport.DISCOVERY_FINDER_URL; @@ -158,7 +160,7 @@ void shouldStartApplicationAndCollectSemanticModels() throws SchemaNotFoundExcep void shouldStopJobAfterDepthIsReached() { // Arrange final String globalAssetIdLevel1 = "globalAssetId"; - final String globalAssetIdLevel2 = "urn:uuid:6d505432-8b31-4966-9514-4b753372683f"; + final String globalAssetIdLevel2 = "urn:uuid:7e4541ea-bb0f-464c-8cb3-021abccbfaf5"; WiremockSupport.successfulSemanticModelRequest(); WiremockSupport.successfulSemanticHubRequests(); @@ -297,7 +299,7 @@ private void successfulRegistryAndDataRequest(final String globalAssetId, final final String registryEdcAssetId = "registry-asset"; successfulNegotiation(registryEdcAssetId); stubFor(getLookupShells200(PUBLIC_LOOKUP_SHELLS_PATH, List.of(shellId)).withQueryParam("assetIds", - containing(globalAssetId))); + equalTo(encodedAssetIds(globalAssetId)))); stubFor(getShellDescriptor200(PUBLIC_SHELL_DESCRIPTORS_PATH + WiremockSupport.encodedId(shellId), bpn, submodelDescriptors, globalAssetId, shellId, idShort)); successfulNegotiation(edcAssetId); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/WiremockSupport.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/WiremockSupport.java index 5146e44de5..33fe3a36c4 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/WiremockSupport.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/WiremockSupport.java @@ -43,10 +43,12 @@ import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.RegisterJob; +import org.eclipse.tractusx.irs.component.assetadministrationshell.IdentifierKeyValuePair; import org.eclipse.tractusx.irs.component.enums.Direction; import org.eclipse.tractusx.irs.data.StringMapper; import org.eclipse.tractusx.irs.edc.client.configuration.JsonLdConfiguration; import org.eclipse.tractusx.irs.edc.client.model.EDRAuthCode; +import org.eclipse.tractusx.irs.registryclient.util.SerializationHelper; import org.eclipse.tractusx.irs.semanticshub.SemanticHubWireMockSupport; import org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockSupport; import org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockSupport; @@ -97,6 +99,14 @@ static String encodedId(final String shellId) { return encodeBase64String(shellId.getBytes(StandardCharsets.UTF_8)); } + static String encodedAssetIds(final String assetIds) { + final IdentifierKeyValuePair globalAssetId = IdentifierKeyValuePair.builder() + .name("globalAssetId") + .value(assetIds) + .build(); + return Base64.getEncoder().encodeToString(new SerializationHelper().serialize(globalAssetId)); + } + static void verifyDiscoveryCalls(final int times) { verify(times, postRequestedFor(urlPathEqualTo(DiscoveryServiceWiremockSupport.DISCOVERY_FINDER_PATH))); verify(times, postRequestedFor(urlPathEqualTo(DiscoveryServiceWiremockSupport.EDC_DISCOVERY_PATH))); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegateTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegateTest.java index f38685a3a8..b4e81769db 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegateTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegateTest.java @@ -62,7 +62,7 @@ void setUp() { @Test void shouldUseDspEndpointIfPresent() throws EdcClientException { // Arrange - when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenReturn(new SubmodelDescriptor("cid", "test")); + when(submodelFacade.getSubmodelPayload(any(), any(), any(), any())).thenReturn(new SubmodelDescriptor("cid", "test")); final Endpoint endpoint = Endpoint.builder() .protocolInformation(ProtocolInformation.builder() .href("http://dataplane.test/123") @@ -77,7 +77,7 @@ void shouldUseDspEndpointIfPresent() throws EdcClientException { // Assert assertThat(submodel).isEqualTo("test"); - verify(submodelFacade, times(1)).getSubmodelPayload("http://edc.test", "http://dataplane.test/123", "123"); + verify(submodelFacade, times(1)).getSubmodelPayload("http://edc.test", "http://dataplane.test/123", "123", "BPN123"); } @Test @@ -85,9 +85,9 @@ void shouldUseDiscoveryFinderIfDspEndpointNotPresent() throws EdcClientException // Arrange final String connector1 = "http://edc.test1"; final String connector2 = "http://edc.test2"; - when(submodelFacade.getSubmodelPayload(eq(connector1), any(), any())).thenThrow( + when(submodelFacade.getSubmodelPayload(eq(connector1), any(), any(), any())).thenThrow( new EdcClientException("test")); - when(submodelFacade.getSubmodelPayload(eq(connector2), any(), any())).thenReturn(new SubmodelDescriptor("cid", "test")); + when(submodelFacade.getSubmodelPayload(eq(connector2), any(), any(), any())).thenReturn(new SubmodelDescriptor("cid", "test")); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of(connector1, connector2)); final String dataplaneUrl = "http://dataplane.test/123"; final Endpoint endpoint = Endpoint.builder() @@ -104,8 +104,8 @@ void shouldUseDiscoveryFinderIfDspEndpointNotPresent() throws EdcClientException // Assert assertThat(submodel).isEqualTo("test"); - verify(submodelFacade, times(1)).getSubmodelPayload(connector1, dataplaneUrl, "123"); - verify(submodelFacade, times(1)).getSubmodelPayload(connector2, dataplaneUrl, "123"); + verify(submodelFacade, times(1)).getSubmodelPayload(connector1, dataplaneUrl, "123", "BPN123"); + verify(submodelFacade, times(1)).getSubmodelPayload(connector2, dataplaneUrl, "123", "BPN123"); verify(connectorEndpointsService, times(1)).fetchConnectorEndpoints(bpn); } @@ -114,7 +114,7 @@ void shouldThrowGenericEdcClientExceptionIfAllEndpointsThrowExceptions() throws // Arrange final String connector1 = "http://edc.test1"; final String connector2 = "http://edc.test2"; - when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenThrow(new EdcClientException("test")); + when(submodelFacade.getSubmodelPayload(any(), any(), any(), any())).thenThrow(new EdcClientException("test")); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of(connector1, connector2)); final String dataplaneUrl = "http://dataplane.test/123"; final Endpoint endpoint = Endpoint.builder() @@ -131,8 +131,8 @@ void shouldThrowGenericEdcClientExceptionIfAllEndpointsThrowExceptions() throws bpn)); // Assert - verify(submodelFacade, times(1)).getSubmodelPayload(connector1, dataplaneUrl, "123"); - verify(submodelFacade, times(1)).getSubmodelPayload(connector2, dataplaneUrl, "123"); + verify(submodelFacade, times(1)).getSubmodelPayload(connector1, dataplaneUrl, "123", "BPN123"); + verify(submodelFacade, times(1)).getSubmodelPayload(connector2, dataplaneUrl, "123", "BPN123"); verify(connectorEndpointsService, times(1)).fetchConnectorEndpoints(bpn); } } \ No newline at end of file diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java index 62159f16b2..fc82ff803c 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java @@ -69,7 +69,7 @@ void shouldFillItemContainerWithRelationshipAndAddChildIdsToProcess() // given final String payload = Files.readString( Paths.get(Objects.requireNonNull(getClass().getResource("/singleLevelBomAsBuilt.json")).toURI())); - when(submodelFacade.getSubmodelPayload(anyString(), anyString(), anyString())).thenReturn(new SubmodelDescriptor("cid", payload)); + when(submodelFacade.getSubmodelPayload(anyString(), anyString(), anyString(), any())).thenReturn(new SubmodelDescriptor("cid", payload)); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("http://localhost")); final ItemContainer.ItemContainerBuilder itemContainerWithShell = ItemContainer.builder() @@ -96,7 +96,7 @@ void shouldFillItemContainerWithUpwardRelationshipAndAddChildIdsToProcess() // given final String payload = Files.readString( Paths.get(Objects.requireNonNull(getClass().getResource("/singleLevelUsageAsBuilt.json")).toURI())); - when(submodelFacade.getSubmodelPayload(anyString(), anyString(), anyString())).thenReturn(new SubmodelDescriptor("cid", payload)); + when(submodelFacade.getSubmodelPayload(anyString(), anyString(), anyString(), any())).thenReturn(new SubmodelDescriptor("cid", payload)); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("http://localhost")); final ItemContainer.ItemContainerBuilder itemContainerWithShell = ItemContainer.builder() @@ -140,7 +140,7 @@ void shouldPutTombstoneForMissingBpn() { @Test void shouldCatchRestClientExceptionAndPutTombstone() throws EdcClientException { // given - when(submodelFacade.getSubmodelPayload(anyString(), anyString(), anyString())).thenThrow( + when(submodelFacade.getSubmodelPayload(anyString(), anyString(), anyString(), any())).thenThrow( new EdcClientException("Unable to call endpoint")); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("http://localhost")); @@ -165,7 +165,7 @@ void shouldCatchRestClientExceptionAndPutTombstone() throws EdcClientException { @Test void shouldCatchJsonParseExceptionAndPutTombstone() throws EdcClientException { // given - when(submodelFacade.getSubmodelPayload(anyString(), anyString(), anyString())).thenThrow( + when(submodelFacade.getSubmodelPayload(anyString(), anyString(), anyString(), any())).thenThrow( new EdcClientException(new Exception("Payload did not match expected submodel"))); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("http://localhost")); final ItemContainer.ItemContainerBuilder itemContainerWithShell = ItemContainer.builder() @@ -197,7 +197,7 @@ void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException "address"))))); // when - when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenThrow(new UsagePolicyException("itemId", null, businessPartnerNumber)); + when(submodelFacade.getSubmodelPayload(any(), any(), any(), any())).thenThrow(new UsagePolicyException("itemId", null, businessPartnerNumber)); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("connector.endpoint.nl")); final ItemContainer result = relationshipDelegate.process(itemContainerWithShell, jobParameter(), new AASTransferProcess(), createKey()); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java index efba84d9a8..f96b066866 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java @@ -152,7 +152,7 @@ void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException "testSingleLevelBomAsBuiltEndpoint"))))); // when - when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenThrow(new UsagePolicyException("itemId", null, businessPartnerNumber)); + when(submodelFacade.getSubmodelPayload(any(), any(), any(), any())).thenThrow(new UsagePolicyException("itemId", null, businessPartnerNumber)); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("connector.endpoint.nl")); final ItemContainer result = submodelDelegate.process(itemContainerShellWithTwoSubmodels, jobParameterCollectAspects(), new AASTransferProcess(), createKey()); @@ -177,7 +177,7 @@ void shouldRequestForAllEndpoints() throws EdcClientException, InvalidSchemaExce ""))))); // when - when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenThrow( + when(submodelFacade.getSubmodelPayload(any(), any(), any(), any())).thenThrow( new ItemNotFoundInCatalogException("test", "itemId")).thenReturn(new SubmodelDescriptor("cid", """ {"test": "test"} """)); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/controller/mock/MockedNotificationReceiverControllerTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/controller/mock/MockedNotificationReceiverControllerTest.java index 4060cbeb86..4310d5582e 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/controller/mock/MockedNotificationReceiverControllerTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/controller/mock/MockedNotificationReceiverControllerTest.java @@ -68,7 +68,7 @@ class MockedNotificationReceiverControllerTest { void shouldReceiveNotificationAndSendMockedNotificationResult() throws Exception { final String bpn = "BPN1"; when(edcDiscoveryMockConfig.getMockEdcResult()).thenReturn(Map.of(bpn, SupplyChainImpacted.YES)); - when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class))).thenReturn( + when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class), anyString())).thenReturn( () -> true); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(new MockHttpServletRequest())); RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(new MockHttpServletRequest())); @@ -82,7 +82,7 @@ void shouldReceiveNotificationAndSendMockedNotificationResult() throws Exception .content(notificationContent) .build()); - verify(edcSubmodelFacade).sendNotification(anyString(), anyString(), any(EdcNotification.class)); + verify(edcSubmodelFacade).sendNotification(anyString(), anyString(), any(EdcNotification.class), anyString()); } @Test diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSenderTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSenderTest.java index f9e785a8f4..c01c2ebe31 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSenderTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSenderTest.java @@ -24,6 +24,7 @@ package org.eclipse.tractusx.irs.ess.service; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -64,7 +65,7 @@ void shouldSendEdcNotificationWithSuccess() throws EdcClientException { // given final EdcNotification edcNotification = prepareNotification( "notification-id"); - when(edcSubmodelFacade.sendNotification(anyString(), anyString(), notificationCaptor.capture())).thenReturn( + when(edcSubmodelFacade.sendNotification(anyString(), anyString(), notificationCaptor.capture(), any())).thenReturn( () -> true); when(connectorEndpointsService.fetchConnectorEndpoints("senderBpn")).thenReturn(List.of("senderEdc")); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListenerTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListenerTest.java index c811a1817f..53bf84b9bb 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListenerTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListenerTest.java @@ -101,7 +101,7 @@ void shouldSendEdcNotificationWhenJobCompleted() throws EdcClientException { // given final String edcBaseUrl = "http://edc-server-url.com"; when(connectorEndpointsService.fetchConnectorEndpoints(anyString())).thenReturn(List.of(edcBaseUrl)); - when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class))).thenReturn( + when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class), any())).thenReturn( () -> true); final JobProcessingFinishedEvent jobProcessingFinishedEvent = new JobProcessingFinishedEvent(jobId.toString(), JobState.COMPLETED.name(), "", Optional.empty()); @@ -111,7 +111,7 @@ void shouldSendEdcNotificationWhenJobCompleted() throws EdcClientException { // then verify(this.edcSubmodelFacade, times(1)).sendNotification(eq(edcBaseUrl), anyString(), - any(EdcNotification.class)); + any(EdcNotification.class), any()); } @Test @@ -121,7 +121,7 @@ void shouldStopProcessingIfNoRelationshipContainsBPN() throws EdcClientException List.of(createRelationship("asPlanned", null, "testParent", "testChild"))); final String edcBaseUrl = "http://edc-server-url.com"; when(connectorEndpointsService.fetchConnectorEndpoints(anyString())).thenReturn(List.of(edcBaseUrl)); - when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class))).thenReturn( + when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class), any())).thenReturn( () -> true); final JobProcessingFinishedEvent jobProcessingFinishedEvent = new JobProcessingFinishedEvent(jobId.toString(), JobState.COMPLETED.name(), "", Optional.empty()); @@ -142,7 +142,7 @@ void shouldHandleCaseWhenRelationshipDoesNotContainBPN() throws EdcClientExcepti createRelationship("asPlanned", null, "parentId2", "childId2"))); final String edcBaseUrl = "http://edc-server-url.com"; when(connectorEndpointsService.fetchConnectorEndpoints(anyString())).thenReturn(List.of(edcBaseUrl)); - when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class))).thenReturn( + when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class), any())).thenReturn( () -> true); final JobProcessingFinishedEvent jobProcessingFinishedEvent = new JobProcessingFinishedEvent(jobId.toString(), JobState.COMPLETED.name(), "", Optional.empty()); @@ -152,7 +152,7 @@ void shouldHandleCaseWhenRelationshipDoesNotContainBPN() throws EdcClientExcepti // then verify(this.edcSubmodelFacade, times(1)).sendNotification(eq(edcBaseUrl), anyString(), - any(EdcNotification.class)); + any(EdcNotification.class), any()); } @Test @@ -161,7 +161,7 @@ void shouldTriggerCorrectNotificationOnNextLevel() throws EdcClientException { createMockForJobIdAndShell(jobId, "bpn", List.of(createRelationship("asPlanned", "BPN1", "parentId1", "childId1"))); final String edcBaseUrl = "http://edc-server-url.com"; - when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class))).thenReturn( + when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class), any())).thenReturn( () -> true); when(connectorEndpointsService.fetchConnectorEndpoints(anyString())).thenReturn(List.of(edcBaseUrl)); final JobProcessingFinishedEvent jobProcessingFinishedEvent = new JobProcessingFinishedEvent(jobId.toString(), @@ -172,7 +172,7 @@ void shouldTriggerCorrectNotificationOnNextLevel() throws EdcClientException { // then verify(this.edcSubmodelFacade, times(1)).sendNotification(eq(edcBaseUrl), eq("notify-request-asset-recursive"), - edcNotificationCaptor.capture()); + edcNotificationCaptor.capture(), any()); assertThat(edcNotificationCaptor.getValue().getHeader().getNotificationType()).isEqualTo( "ess-supplier-request"); final InvestigationNotificationContent content = (InvestigationNotificationContent) edcNotificationCaptor.getValue() @@ -192,7 +192,7 @@ void shouldStopProcessingIfNoEdcAddressIsDiscovered() throws EdcClientException jobProcessingEventListener.handleJobProcessingFinishedEvent(jobProcessingFinishedEvent); // then - verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class)); + verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class), any()); } @Test @@ -207,7 +207,7 @@ void shouldSendCallbackIfNoMoreRelationshipsAreFound() throws EdcClientException jobProcessingEventListener.handleJobProcessingFinishedEvent(jobProcessingFinishedEvent); // then - verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class)); + verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class), any()); verify(this.recursiveNotificationHandler, times(1)).handleNotification(any(), eq(SupplyChainImpacted.NO), eq("bpn"), eq(0)); } @@ -226,7 +226,7 @@ void shouldStopProcessingIfOneOfEdcAddressesIsNotDiscovered() throws EdcClientEx jobProcessingEventListener.handleJobProcessingFinishedEvent(jobProcessingFinishedEvent); // then - verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class)); + verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class), any()); } @Test @@ -238,7 +238,7 @@ void shouldSendEdcRecursiveNotificationWhenJobCompleted() throws EdcClientExcept "urn:uuid:86f69643-3b90-4e34-90bf-789edcf40e7e"))); final String edcBaseUrl = "http://edc-server-url.com"; when(connectorEndpointsService.fetchConnectorEndpoints(anyString())).thenReturn(List.of(edcBaseUrl)); - when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class))).thenReturn( + when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class), any())).thenReturn( () -> true); final JobProcessingFinishedEvent jobProcessingFinishedEvent = new JobProcessingFinishedEvent( recursiveJobId.toString(), JobState.COMPLETED.name(), "", Optional.empty()); @@ -248,7 +248,7 @@ void shouldSendEdcRecursiveNotificationWhenJobCompleted() throws EdcClientExcept // then verify(this.edcSubmodelFacade, times(1)).sendNotification(eq(edcBaseUrl), eq(ASSET_ID_REQUEST_RECURSIVE), - edcNotificationCaptor.capture()); + edcNotificationCaptor.capture(), any()); assertThat(edcNotificationCaptor.getValue().getHeader().getNotificationType()).isEqualTo( "ess-supplier-request"); } @@ -259,7 +259,7 @@ void shouldSendEdcRecursiveNotificationWithMultipleIncidentBPNSs() throws EdcCli createMockForJobIdAndShell(jobId, "bpn", List.of(createRelationship("asPlanned", "BPN1", "parentId1", "childId1")), List.of("BPN1", "BPN2")); final String edcBaseUrl = "http://edc-server-url.com"; - when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class))).thenReturn( + when(edcSubmodelFacade.sendNotification(anyString(), anyString(), any(EdcNotification.class), any())).thenReturn( () -> true); when(connectorEndpointsService.fetchConnectorEndpoints(anyString())).thenReturn(List.of(edcBaseUrl)); final JobProcessingFinishedEvent jobProcessingFinishedEvent = new JobProcessingFinishedEvent(jobId.toString(), @@ -270,14 +270,14 @@ void shouldSendEdcRecursiveNotificationWithMultipleIncidentBPNSs() throws EdcCli // then verify(this.edcSubmodelFacade, times(1)).sendNotification(eq(edcBaseUrl), eq("notify-request-asset-recursive"), - edcNotificationCaptor.capture()); + edcNotificationCaptor.capture(), any()); final InvestigationNotificationContent content = (InvestigationNotificationContent) edcNotificationCaptor.getValue() .getContent(); assertThat(edcNotificationCaptor.getValue().getHeader().getNotificationType()).isEqualTo( "ess-supplier-request"); assertThat(content.getIncidentBPNSs()).containsAll(List.of("BPN1", "BPN2")); assertThat(content.getConcernedCatenaXIds()).containsAll(List.of("childId1")); - verify(this.edcSubmodelFacade, times(1)).sendNotification(any(), any(), any(EdcNotification.class)); + verify(this.edcSubmodelFacade, times(1)).sendNotification(any(), any(), any(EdcNotification.class), any()); } @Test @@ -292,7 +292,7 @@ void shouldCreateTombstoneWhenAspectModelsMissing() throws EdcClientException { jobProcessingEventListener.handleJobProcessingFinishedEvent(finishedEvent); // then - verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class)); + verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class), any()); final Optional job = bpnInvestigationJobCache.findByJobId(jobId); assertThat(job).isPresent(); assertThat(job.get().getJobSnapshot().getTombstones()).hasSize(2); @@ -310,7 +310,7 @@ void shouldCreateTombstoneWhenSiteIdIsMissing() throws EdcClientException { jobProcessingEventListener.handleJobProcessingFinishedEvent(finishedEvent); // then - verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class)); + verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class), any()); final Optional job = bpnInvestigationJobCache.findByJobId(jobId); assertThat(job).isPresent(); assertThat(job.get().getJobSnapshot().getTombstones()).hasSize(1); diff --git a/irs-common/src/main/java/org/eclipse/tractusx/irs/common/persistence/BlobPersistence.java b/irs-common/src/main/java/org/eclipse/tractusx/irs/common/persistence/BlobPersistence.java index d8a38fe6be..03e2256ff5 100644 --- a/irs-common/src/main/java/org/eclipse/tractusx/irs/common/persistence/BlobPersistence.java +++ b/irs-common/src/main/java/org/eclipse/tractusx/irs/common/persistence/BlobPersistence.java @@ -26,6 +26,7 @@ import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; /** @@ -33,10 +34,14 @@ */ public interface BlobPersistence { + String DEFAULT_BLOB_NAME = "default"; + void putBlob(String targetBlobName, byte[] blob) throws BlobPersistenceException; Optional getBlob(String sourceBlobName) throws BlobPersistenceException; + Map getAllBlobs() throws BlobPersistenceException; + Collection findBlobByPrefix(String prefix) throws BlobPersistenceException; boolean delete(String blobId, List processIds) throws BlobPersistenceException; diff --git a/irs-common/src/main/java/org/eclipse/tractusx/irs/common/persistence/MinioBlobPersistence.java b/irs-common/src/main/java/org/eclipse/tractusx/irs/common/persistence/MinioBlobPersistence.java index 5bbe56598c..d05906cf32 100644 --- a/irs-common/src/main/java/org/eclipse/tractusx/irs/common/persistence/MinioBlobPersistence.java +++ b/irs-common/src/main/java/org/eclipse/tractusx/irs/common/persistence/MinioBlobPersistence.java @@ -29,7 +29,9 @@ import java.security.NoSuchAlgorithmException; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -78,14 +80,17 @@ public MinioBlobPersistence(final String endpoint, final String accessKey, final this(bucketName, createClient(endpoint, accessKey, secretKey), daysToLive); } - public MinioBlobPersistence(final String bucketName, final MinioClient client, final int daysToLive) throws BlobPersistenceException { + public MinioBlobPersistence(final String bucketName, final MinioClient client, final int daysToLive) + throws BlobPersistenceException { this.bucketName = bucketName; this.minioClient = client; this.daysToLive = daysToLive; try { createBucketIfNotExists(bucketName); - } catch (ServerException | InsufficientDataException | ErrorResponseException | IOException | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException e) { + } catch (ServerException | InsufficientDataException | ErrorResponseException | IOException + | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException + | InternalException e) { throw new BlobPersistenceException("Encountered error while trying to create min.io client", e); } } @@ -140,7 +145,9 @@ public void putBlob(final String targetBlobName, final byte[] blob) throws BlobP .stream(byteArrayInputStream, byteArrayInputStream.available(), -1) .build()); log.debug("Saving to bucket name {} with object name {}", bucketName, targetBlobName); - } catch (ServerException | InsufficientDataException | ErrorResponseException | IOException | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException e) { + } catch (ServerException | InsufficientDataException | ErrorResponseException | IOException + | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException + | InternalException e) { throw new BlobPersistenceException("Encountered error while trying to store blob", e); } } @@ -155,7 +162,8 @@ public Optional getBlob(final String sourceBlobName) throws BlobPersiste return Optional.empty(); } throw createLoadFailedException(e); - } catch (ServerException | InsufficientDataException | IOException | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException e) { + } catch (ServerException | InsufficientDataException | IOException | NoSuchAlgorithmException + | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException e) { throw createLoadFailedException(e); } try (response) { @@ -163,7 +171,31 @@ public Optional getBlob(final String sourceBlobName) throws BlobPersiste } catch (IOException e) { throw createLoadFailedException(e); } + } + + /** + * @return Map of bpn to matching blobs + */ + @Override + public Map getAllBlobs() throws BlobPersistenceException { + final Iterable> items = getItems(); + final Map result = new ConcurrentHashMap<>(); + for (final Result item : items) { + try { + final String objectName = item.get().objectName(); + try (GetObjectResponse response = minioClient.getObject( + GetObjectArgs.builder().bucket(bucketName).object(objectName).build())) { + result.put(objectName, response.readAllBytes()); + } + } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException + | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException + | XmlParserException e) { + throw createLoadFailedException(e); + } + } + + return result; } private BlobPersistenceException createLoadFailedException(final Throwable cause) { @@ -194,7 +226,8 @@ public boolean delete(final String sourceBlobName, final List processIds } else { throw new BlobPersistenceException("Encountered error while trying to delete blob", e); } - } catch (ServerException | InsufficientDataException | IOException | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException e) { + } catch (ServerException | InsufficientDataException | IOException | NoSuchAlgorithmException + | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException e) { throw new BlobPersistenceException("Encountered error while trying to delete blob", e); } } @@ -203,7 +236,9 @@ private void deleteConnectedProcessesBlobs(final List processIds) { processIds.forEach(processId -> { try { minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(processId).build()); - } catch (ServerException | InsufficientDataException | IOException | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException | ErrorResponseException e) { + } catch (ServerException | InsufficientDataException | IOException | NoSuchAlgorithmException + | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException + | ErrorResponseException e) { log.info("No object data with process Id {} found", processId); } }); @@ -221,10 +256,16 @@ private Stream getBlobIfPresent(final String sourceBlobName) { private Stream getItem(final Result result) { try { return Stream.of(result.get()); - } catch (ServerException | InsufficientDataException | ErrorResponseException | IOException | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException | InternalException e) { + } catch (ServerException | InsufficientDataException | ErrorResponseException | IOException + | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException + | InternalException e) { log.error("Encountered error while trying to retrieve result content", e); return Stream.empty(); } } + private Iterable> getItems() { + return minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build()); + } + } diff --git a/irs-common/src/test/java/org/eclipse/tractusx/irs/common/persistence/MinioBlobPersistenceTest.java b/irs-common/src/test/java/org/eclipse/tractusx/irs/common/persistence/MinioBlobPersistenceTest.java index e62a2ae9e6..c0bc89d951 100644 --- a/irs-common/src/test/java/org/eclipse/tractusx/irs/common/persistence/MinioBlobPersistenceTest.java +++ b/irs-common/src/test/java/org/eclipse/tractusx/irs/common/persistence/MinioBlobPersistenceTest.java @@ -32,10 +32,18 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Stream; @@ -43,8 +51,16 @@ import io.minio.MinioClient; import io.minio.Result; import io.minio.errors.ErrorResponseException; +import io.minio.errors.InsufficientDataException; +import io.minio.errors.InternalException; +import io.minio.errors.InvalidResponseException; +import io.minio.errors.ServerException; +import io.minio.errors.XmlParserException; +import io.minio.messages.Contents; import io.minio.messages.ErrorResponse; import io.minio.messages.Item; +import lombok.AllArgsConstructor; +import okhttp3.Headers; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -217,4 +233,36 @@ void shouldNotFindBlobByPrefix() throws Exception { assertThat(blobsByPrefix).isEmpty(); } + @Test + void shouldReturnAllBlobs() throws BlobPersistenceException, ServerException, InsufficientDataException, ErrorResponseException, + IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, + InternalException { + final String name = "test-name"; + when(client.listObjects(any())).thenReturn(List.of(new Result<>(new TestItem(name)))); + + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeUTF(""); + InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + ObjectInputStream outputStream = new ObjectInputStream(inputStream); + + when(client.getObject(any())).thenReturn(new GetObjectResponse(null, null, null, null, outputStream)); + + // act + final Map allBlobs = testee.getAllBlobs(); + + // assert + assertThat(allBlobs.get(name)).isNotNull(); + } + + @AllArgsConstructor + static class TestItem extends Item { + + private final String name; + + @Override + public String objectName() { + return name; + } + } } \ No newline at end of file diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationService.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationService.java index 9abecd843e..00205d2ec7 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationService.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationService.java @@ -65,7 +65,7 @@ public class ContractNegotiationService { private final EdcConfiguration config; public NegotiationResponse negotiate(final String providerConnectorUrl, final CatalogItem catalogItem, - final EndpointDataReferenceStatus endpointDataReferenceStatus) + final EndpointDataReferenceStatus endpointDataReferenceStatus, final String bpn) throws ContractNegotiationException, UsagePolicyException, TransferProcessException { EndpointDataReferenceStatus resultEndpointDataReferenceStatus; @@ -85,7 +85,7 @@ public NegotiationResponse negotiate(final String providerConnectorUrl, final Ca switch (resultEndpointDataReferenceStatus.tokenStatus()) { case REQUIRED_NEW -> { final CompletableFuture responseFuture = startNewNegotiation(providerConnectorUrl, - catalogItem); + catalogItem, bpn); negotiationResponse = Objects.requireNonNull(getNegotiationResponse(responseFuture)); contractAgreementId = negotiationResponse.getContractAgreementId(); } @@ -120,10 +120,10 @@ public NegotiationResponse negotiate(final String providerConnectorUrl, final Ca } private CompletableFuture startNewNegotiation(final String providerConnectorUrl, - final CatalogItem catalogItem) throws UsagePolicyException { + final CatalogItem catalogItem, final String bpn) throws UsagePolicyException { log.info("Staring new contract negotiation."); - if (!policyCheckerService.isValid(catalogItem.getPolicy())) { + if (!policyCheckerService.isValid(catalogItem.getPolicy(), bpn)) { log.info("Policy was not allowed, canceling negotiation."); throw new UsagePolicyException(catalogItem.getItemId(), catalogItem.getPolicy(), catalogItem.getConnectorId()); diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClient.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClient.java index 0d8fae946e..b1222f6f43 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClient.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClient.java @@ -37,20 +37,20 @@ /** * Public API facade for EDC domain */ -@SuppressWarnings("PMD.ExcessiveImports") +@SuppressWarnings({"PMD.ExcessiveImports", "PMD.UseObjectForClearerAPI"}) public interface EdcSubmodelClient { CompletableFuture getSubmodelPayload(String connectorEndpoint, String submodelDataplaneUrl, - String assetId) throws EdcClientException; + String assetId, String bpn) throws EdcClientException; CompletableFuture sendNotification(String submodelEndpointAddress, String assetId, - EdcNotification notification) throws EdcClientException; + EdcNotification notification, String bpn) throws EdcClientException; List> getEndpointReferencesForAsset(String endpointAddress, - String filterKey, String filterValue) throws EdcClientException; + String filterKey, String filterValue, String bpn) throws EdcClientException; List> getEndpointReferencesForAsset(String endpointAddress, - String filterKey, String filterValue, EndpointDataReferenceStatus cachedEndpointDataReference) + String filterKey, String filterValue, EndpointDataReferenceStatus cachedEndpointDataReference, String bpn) throws EdcClientException; } diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientImpl.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientImpl.java index 4160a53f84..601fa53403 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientImpl.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientImpl.java @@ -64,7 +64,8 @@ @Slf4j @RequiredArgsConstructor @SuppressWarnings({ "PMD.TooManyMethods", - "PMD.ExcessiveImports" + "PMD.ExcessiveImports", + "PMD.UseObjectForClearerAPI" }) public class EdcSubmodelClientImpl implements EdcSubmodelClient { @@ -147,15 +148,14 @@ private Optional sendSubmodelNotification(final String @Override public CompletableFuture getSubmodelPayload(final String connectorEndpoint, - final String submodelDataplaneUrl, final String assetId) throws EdcClientException { + final String submodelDataplaneUrl, final String assetId, final String bpn) throws EdcClientException { final CheckedSupplier> waitingForSubmodelRetrieval = () -> { - log.info("Requesting raw SubmodelPayload for endpoint '{}'.", connectorEndpoint); final StopWatch stopWatch = new StopWatch(); stopWatch.start("Get EDC Submodel task for raw payload, endpoint " + connectorEndpoint); - final EndpointDataReference dataReference = getEndpointDataReference(connectorEndpoint, assetId); + final EndpointDataReference dataReference = getEndpointDataReference(connectorEndpoint, assetId, bpn); return pollingService.createJob() .action(() -> retrieveSubmodelData(submodelDataplaneUrl, stopWatch, dataReference)) @@ -168,7 +168,7 @@ public CompletableFuture getSubmodelPayload(final String con return execute(connectorEndpoint, waitingForSubmodelRetrieval); } - private EndpointDataReference getEndpointDataReference(final String connectorEndpoint, final String assetId) + private EndpointDataReference getEndpointDataReference(final String connectorEndpoint, final String assetId, final String bpn) throws EdcClientException { final EndpointDataReference result; @@ -180,18 +180,18 @@ private EndpointDataReference getEndpointDataReference(final String connectorEnd log.info("Endpoint data reference found in cache with token status valid, reusing cache record."); result = cachedReference.endpointDataReference(); } else { - result = getEndpointDataReferenceAndAddToStorage(connectorEndpoint, assetId, cachedReference); + result = getEndpointDataReferenceAndAddToStorage(connectorEndpoint, assetId, cachedReference, bpn); } return result; } private EndpointDataReference getEndpointDataReferenceAndAddToStorage(final String connectorEndpoint, - final String assetId, final EndpointDataReferenceStatus cachedEndpointDataReference) + final String assetId, final EndpointDataReferenceStatus cachedEndpointDataReference, final String bpn) throws EdcClientException { try { final EndpointDataReference endpointDataReference = awaitEndpointReferenceForAsset(connectorEndpoint, - NAMESPACE_EDC_ID, assetId, cachedEndpointDataReference).get(); + NAMESPACE_EDC_ID, assetId, cachedEndpointDataReference, bpn).get(); endpointDataReferenceCacheService.putEndpointDataReferenceIntoStorage(assetId, endpointDataReference); return endpointDataReference; @@ -205,12 +205,11 @@ private EndpointDataReference getEndpointDataReferenceAndAddToStorage(final Stri @Override public CompletableFuture sendNotification(final String connectorEndpoint, - final String assetId, final EdcNotification notification) throws EdcClientException { - + final String assetId, final EdcNotification notification, final String bpn) throws EdcClientException { return execute(connectorEndpoint, () -> { final StopWatch stopWatch = new StopWatch(); stopWatch.start("Send EDC notification task, endpoint " + connectorEndpoint); - final EndpointDataReference endpointDataReference = getEndpointDataReference(connectorEndpoint, assetId); + final EndpointDataReference endpointDataReference = getEndpointDataReference(connectorEndpoint, assetId, bpn); return sendNotificationAsync(assetId, notification, stopWatch, endpointDataReference); }); @@ -218,16 +217,15 @@ public CompletableFuture sendNotification(final String @Override public List> getEndpointReferencesForAsset(final String endpointAddress, - final String filterKey, final String filterValue) throws EdcClientException { + final String filterKey, final String filterValue, final String bpn) throws EdcClientException { return execute(endpointAddress, () -> getEndpointReferencesForAsset(endpointAddress, filterKey, filterValue, - new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW))); + new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW), bpn)); } @Override public List> getEndpointReferencesForAsset(final String endpointAddress, final String filterKey, final String filterValue, - final EndpointDataReferenceStatus endpointDataReferenceStatus) throws EdcClientException { - + final EndpointDataReferenceStatus endpointDataReferenceStatus, final String bpn) throws EdcClientException { final StopWatch stopWatch = new StopWatch(); stopWatch.start("Get EDC Submodel task for shell descriptor, endpoint " + endpointAddress); @@ -250,7 +248,7 @@ public List> getEndpointReferencesForAs final NegotiationResponse negotiationResponse; try { - negotiationResponse = negotiateContract(endpointDataReferenceStatus, contractOffer, providerWithSuffix); + negotiationResponse = negotiateContract(endpointDataReferenceStatus, contractOffer, providerWithSuffix, bpn); final String storageId = getStorageId(endpointDataReferenceStatus, negotiationResponse); @@ -271,11 +269,11 @@ public List> getEndpointReferencesForAs } private NegotiationResponse negotiateContract(final EndpointDataReferenceStatus endpointDataReferenceStatus, - final CatalogItem catalogItem, final String providerWithSuffix) throws EdcClientException { + final CatalogItem catalogItem, final String providerWithSuffix, final String bpn) throws EdcClientException { final NegotiationResponse response; try { response = contractNegotiationService.negotiate(providerWithSuffix, catalogItem, - endpointDataReferenceStatus); + endpointDataReferenceStatus, bpn); } catch (TransferProcessException | UsagePolicyException | ContractNegotiationException e) { throw new EdcClientException(("Negotiation failed for endpoint '%s', " + "tokenStatus '%s', " + "providerWithSuffix '%s', catalogItem '%s'").formatted( @@ -287,7 +285,7 @@ private NegotiationResponse negotiateContract(final EndpointDataReferenceStatus private CompletableFuture awaitEndpointReferenceForAsset(final String endpointAddress, final String filterKey, final String filterValue, - final EndpointDataReferenceStatus endpointDataReferenceStatus) throws EdcClientException { + final EndpointDataReferenceStatus endpointDataReferenceStatus, final String bpn) throws EdcClientException { final StopWatch stopWatch = new StopWatch(); stopWatch.start("Get EDC Submodel task for shell descriptor, endpoint " + endpointAddress); @@ -296,7 +294,7 @@ private CompletableFuture awaitEndpointReferenceForAsset( final List items = catalogFacade.fetchCatalogByFilter(providerWithSuffix, filterKey, filterValue); final NegotiationResponse response = contractNegotiationService.negotiate(providerWithSuffix, - items.stream().findFirst().orElseThrow(), endpointDataReferenceStatus); + items.stream().findFirst().orElseThrow(), endpointDataReferenceStatus, bpn); final String storageId = getStorageId(endpointDataReferenceStatus, response); diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientLocalStub.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientLocalStub.java index 5fb8796813..9ac58b2bd1 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientLocalStub.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientLocalStub.java @@ -41,6 +41,7 @@ /** * Submodel facade stub used in local environment */ +@SuppressWarnings("PMD.UseObjectForClearerAPI") public class EdcSubmodelClientLocalStub implements EdcSubmodelClient { private final SubmodelTestdataCreator testdataCreator; @@ -52,7 +53,7 @@ public EdcSubmodelClientLocalStub(final CxTestDataContainer cxTestDataContainer) @Override public CompletableFuture getSubmodelPayload(final String connectorEndpoint, - final String submodelDataplaneUrl, final String assetId) throws EdcClientException { + final String submodelDataplaneUrl, final String assetId, final String bpn) throws EdcClientException { if ("urn:uuid:c35ee875-5443-4a2d-bc14-fdacd64b9446".equals(assetId)) { throw new EdcClientException("Dummy Exception"); } @@ -63,7 +64,7 @@ public CompletableFuture getSubmodelPayload(final String con @Override public CompletableFuture sendNotification(final String submodelEndpointAddress, - final String assetId, final EdcNotification notification) { + final String assetId, final EdcNotification notification, final String bpn) { // not actually sending anything, just return success response return CompletableFuture.completedFuture(() -> true); } @@ -71,13 +72,13 @@ public CompletableFuture sendNotification(final String @Override public List> getEndpointReferencesForAsset(final String endpointAddress, final String filterKey, final String filterValue, - final EndpointDataReferenceStatus cachedEndpointDataReference) throws EdcClientException { + final EndpointDataReferenceStatus cachedEndpointDataReference, final String bpn) throws EdcClientException { throw new EdcClientException("Not implemented"); } @Override public List> getEndpointReferencesForAsset(final String endpointAddress, - final String filterKey, final String filterValue) throws EdcClientException { + final String filterKey, final String filterValue, final String bpn) throws EdcClientException { throw new EdcClientException("Not implemented"); } } diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelFacade.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelFacade.java index 20ee2f59bc..e99107d1de 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelFacade.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelFacade.java @@ -43,7 +43,7 @@ */ @Slf4j @RequiredArgsConstructor -@SuppressWarnings("PMD.AvoidDuplicateLiterals") +@SuppressWarnings({"PMD.AvoidDuplicateLiterals", "PMD.UseObjectForClearerAPI"}) public class EdcSubmodelFacade { private final EdcSubmodelClient client; @@ -52,9 +52,9 @@ public class EdcSubmodelFacade { @SuppressWarnings("PMD.PreserveStackTrace") public SubmodelDescriptor getSubmodelPayload(final String connectorEndpoint, final String submodelDataplaneUrl, - final String assetId) throws EdcClientException { + final String assetId, final String bpn) throws EdcClientException { try { - return client.getSubmodelPayload(connectorEndpoint, submodelDataplaneUrl, assetId) + return client.getSubmodelPayload(connectorEndpoint, submodelDataplaneUrl, assetId, bpn) .get(config.getAsyncTimeoutMillis(), TimeUnit.MILLISECONDS); } catch (InterruptedException e) { log.debug("InterruptedException occurred.", e); @@ -74,10 +74,10 @@ public SubmodelDescriptor getSubmodelPayload(final String connectorEndpoint, fin @SuppressWarnings("PMD.PreserveStackTrace") public EdcNotificationResponse sendNotification(final String submodelEndpointAddress, final String assetId, - final EdcNotification notification) throws EdcClientException { + final EdcNotification notification, final String bpn) throws EdcClientException { try { log.debug("Sending EDC Notification '{}'", notification); - return client.sendNotification(submodelEndpointAddress, assetId, notification) + return client.sendNotification(submodelEndpointAddress, assetId, notification, bpn) .get(config.getAsyncTimeoutMillis(), TimeUnit.MILLISECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); @@ -94,8 +94,8 @@ public EdcNotificationResponse sendNotification(final String submodelEndpointAdd } public List> getEndpointReferencesForAsset(final String endpointAddress, - final String filterKey, final String filterValue) throws EdcClientException { - return client.getEndpointReferencesForAsset(endpointAddress, filterKey, filterValue); + final String filterKey, final String filterValue, final String bpn) throws EdcClientException { + return client.getEndpointReferencesForAsset(endpointAddress, filterKey, filterValue, bpn); } } diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/AcceptedPoliciesProvider.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/AcceptedPoliciesProvider.java index 8f4ffbce3d..c33707d3ba 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/AcceptedPoliciesProvider.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/AcceptedPoliciesProvider.java @@ -33,7 +33,7 @@ * Provides policies to be accepted during EDC negotiation */ public interface AcceptedPoliciesProvider { - List getAcceptedPolicies(); + List getAcceptedPolicies(String bpn); /** * Default provider if no other beans are loaded. @@ -46,7 +46,7 @@ class DefaultAcceptedPoliciesProvider implements AcceptedPoliciesProvider { private final List acceptedPolicies = new ArrayList<>(); @Override - public List getAcceptedPolicies() { + public List getAcceptedPolicies(final String bpn) { return List.copyOf(acceptedPolicies); } diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerService.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerService.java index 0dbe398aad..062bdafad8 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerService.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerService.java @@ -43,8 +43,8 @@ public class PolicyCheckerService { private final AcceptedPoliciesProvider policyStore; private final ConstraintCheckerService constraintCheckerService; - public boolean isValid(final Policy policy) { - return policy.getPermissions().stream().allMatch(permission -> isValid(permission, getValidStoredPolicies())); + public boolean isValid(final Policy policy, final String bpn) { + return policy.getPermissions().stream().allMatch(permission -> isValid(permission, getValidStoredPolicies(bpn))); } private boolean isValid(final Permission permission, final List validStoredPolicies) { @@ -53,8 +53,8 @@ private boolean isValid(final Permission permission, final List acceptedPolicy.policy(), permission.getConstraints())); } - private List getValidStoredPolicies() { - return policyStore.getAcceptedPolicies() + private List getValidStoredPolicies(final String bpn) { + return policyStore.getAcceptedPolicies(bpn) .stream() .filter(p -> p.validUntil().isAfter(OffsetDateTime.now())) .toList(); diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationServiceTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationServiceTest.java index 8ac92edb92..18ee578180 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationServiceTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationServiceTest.java @@ -84,7 +84,7 @@ void shouldNegotiateSuccessfully() final var assetId = "testTarget"; final String offerId = "offerId"; final CatalogItem catalogItem = createCatalogItem(assetId, offerId); - when(policyCheckerService.isValid(any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); when(edcControlPlaneClient.startNegotiations(any())).thenReturn( Response.builder().responseId("negotiationId").build()); CompletableFuture response = CompletableFuture.completedFuture( @@ -97,7 +97,7 @@ void shouldNegotiateSuccessfully() // act NegotiationResponse result = testee.negotiate(CONNECTOR_URL, catalogItem, - new EndpointDataReferenceStatus(null, EndpointDataReferenceStatus.TokenStatus.REQUIRED_NEW)); + new EndpointDataReferenceStatus(null, EndpointDataReferenceStatus.TokenStatus.REQUIRED_NEW), "bpn"); // assert assertThat(result).isNotNull(); @@ -110,7 +110,7 @@ void shouldThrowErrorWhenRetrievingNegotiationResult() { final var assetId = "testTarget"; final String offerId = "offerId"; final CatalogItem catalogItem = createCatalogItem(assetId, offerId); - when(policyCheckerService.isValid(any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); when(edcControlPlaneClient.startNegotiations(any())).thenReturn( Response.builder().responseId("negotiationId").build()); CompletableFuture response = CompletableFuture.failedFuture( @@ -119,7 +119,7 @@ void shouldThrowErrorWhenRetrievingNegotiationResult() { // act & assert assertThatThrownBy(() -> testee.negotiate(CONNECTOR_URL, catalogItem, new EndpointDataReferenceStatus(null, - EndpointDataReferenceStatus.TokenStatus.REQUIRED_NEW))).isInstanceOf(EdcClientException.class); + EndpointDataReferenceStatus.TokenStatus.REQUIRED_NEW), "bpn")).isInstanceOf(EdcClientException.class); } @Test @@ -128,7 +128,7 @@ void shouldThrowErrorWhenRetrievingTransferResult() { final var assetId = "testTarget"; final String offerId = "offerId"; final CatalogItem catalogItem = createCatalogItem(assetId, offerId); - when(policyCheckerService.isValid(any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); when(edcControlPlaneClient.startNegotiations(any())).thenReturn( Response.builder().responseId("negotiationId").build()); @@ -144,7 +144,7 @@ void shouldThrowErrorWhenRetrievingTransferResult() { // act & assert assertThatThrownBy(() -> testee.negotiate(CONNECTOR_URL, catalogItem, new EndpointDataReferenceStatus(null, - EndpointDataReferenceStatus.TokenStatus.REQUIRED_NEW))).isInstanceOf(EdcClientException.class); + EndpointDataReferenceStatus.TokenStatus.REQUIRED_NEW), "bpn")).isInstanceOf(EdcClientException.class); } @Test @@ -156,11 +156,11 @@ void shouldThrowErrorWhenPolicyCheckerReturnFalse() { .policy(createPolicy(assetId)) .assetPropId(assetId) .build(); - when(policyCheckerService.isValid(any())).thenReturn(Boolean.FALSE); + when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.FALSE); // act & assert assertThatThrownBy(() -> testee.negotiate(CONNECTOR_URL, catalogItem, new EndpointDataReferenceStatus(null, - EndpointDataReferenceStatus.TokenStatus.REQUIRED_NEW))).isInstanceOf(EdcClientException.class); + EndpointDataReferenceStatus.TokenStatus.REQUIRED_NEW), "bpn")).isInstanceOf(EdcClientException.class); } @Test @@ -170,7 +170,7 @@ void shouldStartNegotiationProcessWhenTokenStatusIsRequiredNew() final var assetId = "testTarget"; final String offerId = "offerId"; final CatalogItem catalogItem = createCatalogItem(assetId, offerId); - when(policyCheckerService.isValid(any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); when(edcControlPlaneClient.startNegotiations(any())).thenReturn( Response.builder().responseId("negotiationId").build()); CompletableFuture negotiationResponse = CompletableFuture.completedFuture( @@ -183,7 +183,7 @@ void shouldStartNegotiationProcessWhenTokenStatusIsRequiredNew() // when testee.negotiate(CONNECTOR_URL, catalogItem, - new EndpointDataReferenceStatus(null, EndpointDataReferenceStatus.TokenStatus.REQUIRED_NEW)); + new EndpointDataReferenceStatus(null, EndpointDataReferenceStatus.TokenStatus.REQUIRED_NEW), "bpn"); // then verify(edcControlPlaneClient).startNegotiations(any()); @@ -196,7 +196,7 @@ void shouldStartNegotiationProcessWhenTokenStatusIsMissing() final var assetId = "testTarget"; final String offerId = "offerId"; final CatalogItem catalogItem = createCatalogItem(assetId, offerId); - when(policyCheckerService.isValid(any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); when(edcControlPlaneClient.startNegotiations(any())).thenReturn( Response.builder().responseId("negotiationId").build()); CompletableFuture negotiationResponse = CompletableFuture.completedFuture( @@ -208,7 +208,7 @@ void shouldStartNegotiationProcessWhenTokenStatusIsMissing() CompletableFuture.completedFuture(TransferProcessResponse.builder().build())); // when - testee.negotiate(CONNECTOR_URL, catalogItem, null); + testee.negotiate(CONNECTOR_URL, catalogItem, null, "bpn"); // then verify(edcControlPlaneClient).startNegotiations(any()); @@ -231,7 +231,7 @@ void shouldNotStartNewNegotiationWhenTokenIsExpired() // when testee.negotiate(CONNECTOR_URL, catalogItem, new EndpointDataReferenceStatus( EndpointDataReference.Builder.newInstance().authKey("").authCode(encodedAuthCode).endpoint("").build(), - EndpointDataReferenceStatus.TokenStatus.EXPIRED)); + EndpointDataReferenceStatus.TokenStatus.EXPIRED), "bpn"); // then verify(edcControlPlaneClient, never()).startNegotiations(any()); @@ -248,7 +248,7 @@ void shouldThrowInvalidStateExceptionWhenTokenIsValid() { // then assertThatThrownBy(() -> testee.negotiate(CONNECTOR_URL, catalogItem, new EndpointDataReferenceStatus( EndpointDataReference.Builder.newInstance().authKey("").endpoint("").authCode("").build(), - EndpointDataReferenceStatus.TokenStatus.VALID))).isInstanceOf(IllegalStateException.class); + EndpointDataReferenceStatus.TokenStatus.VALID), "bpn")).isInstanceOf(IllegalStateException.class); } } \ No newline at end of file diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientLocalStubTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientLocalStubTest.java index 9be5557c9c..f979c91a8e 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientLocalStubTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientLocalStubTest.java @@ -47,6 +47,6 @@ void shouldThrowExceptionFor() { String assetId = "urn:uuid:c35ee875-5443-4a2d-bc14-fdacd64b9446"; // when - assertThrows(EdcClientException.class, () -> edcSubmodelClientLocalStub.getSubmodelPayload("", "", assetId)); + assertThrows(EdcClientException.class, () -> edcSubmodelClientLocalStub.getSubmodelPayload("", "", assetId, "")); } } \ No newline at end of file diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientTest.java index c65a83b62c..f800bc7a5a 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientTest.java @@ -136,7 +136,7 @@ void shouldRetrieveValidRelationship() throws Exception { when(catalogFacade.fetchCatalogByFilter(any(), any(), any())).thenReturn( List.of(CatalogItem.builder().itemId("itemId").build())); when(contractNegotiationService.negotiate(any(), any(), - eq(new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)))).thenReturn( + eq(new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)), any())).thenReturn( NegotiationResponse.builder().contractAgreementId(agreementId).build()); final EndpointDataReference ref = TestMother.endpointDataReference(agreementId); when(endpointDataReferenceCacheService.getEndpointDataReferenceFromStorage(agreementId)).thenReturn( @@ -147,7 +147,7 @@ void shouldRetrieveValidRelationship() throws Exception { new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)); // act - final var result = testee.getSubmodelPayload(ENDPOINT_ADDRESS, "suffix", "assetId"); + final var result = testee.getSubmodelPayload(ENDPOINT_ADDRESS, "suffix", "assetId", "bpn"); final String resultingRelationships = result.get(5, TimeUnit.SECONDS).getPayload(); // assert @@ -163,7 +163,7 @@ void shouldSendNotificationSuccessfully() throws Exception { final EdcNotification notification = EdcNotification.builder().build(); when(catalogFacade.fetchCatalogByFilter(any(), any(), any())).thenReturn( List.of(CatalogItem.builder().itemId("itemId").build())); - when(contractNegotiationService.negotiate(any(), any(), any())).thenReturn( + when(contractNegotiationService.negotiate(any(), any(), any(), any())).thenReturn( NegotiationResponse.builder().contractAgreementId(agreementId).build()); final EndpointDataReference ref = mock(EndpointDataReference.class); when(endpointDataReferenceCacheService.getEndpointDataReferenceFromStorage(agreementId)).thenReturn( @@ -173,7 +173,7 @@ void shouldSendNotificationSuccessfully() throws Exception { new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)); // act - final var result = testee.sendNotification(CONNECTOR_ENDPOINT, "notify-request-asset", notification); + final var result = testee.sendNotification(CONNECTOR_ENDPOINT, "notify-request-asset", notification, "bpn"); final EdcNotificationResponse response = result.get(5, TimeUnit.SECONDS); // assert @@ -204,7 +204,7 @@ void shouldReturnRelationshipsWhenRequestingWithCatenaXIdAndSingleLevelBomAsBuil new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)); // act - final String submodelResponse = testee.getSubmodelPayload("http://localhost/", "/submodel", ASSET_ID) + final String submodelResponse = testee.getSubmodelPayload("http://localhost/", "/submodel", ASSET_ID, "bpn") .get(5, TimeUnit.SECONDS) .getPayload(); @@ -225,7 +225,7 @@ void shouldReturnRelationshipsWhenRequestingWithCatenaXIdAndSingleLevelBomAsPlan new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)); // act - final String submodelResponse = testee.getSubmodelPayload("http://localhost/", "/submodel", ASSET_ID) + final String submodelResponse = testee.getSubmodelPayload("http://localhost/", "/submodel", ASSET_ID, "bpn") .get(5, TimeUnit.SECONDS) .getPayload(); @@ -246,7 +246,7 @@ void shouldReturnRelationshipsWhenRequestingWithCatenaXIdAndSingleLevelBomAsSpec new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)); // act - final String submodelResponse = testee.getSubmodelPayload("http://localhost/", "/submodel", ASSET_ID) + final String submodelResponse = testee.getSubmodelPayload("http://localhost/", "/submodel", ASSET_ID, "bpn") .get(5, TimeUnit.SECONDS) .getPayload(); @@ -267,7 +267,7 @@ void shouldReturnEmptyRelationshipsWhenRequestingWithCatenaXIdAndSingleLevelUsag new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)); // act - final String submodelResponse = testee.getSubmodelPayload("http://localhost/", "/submodel", ASSET_ID) + final String submodelResponse = testee.getSubmodelPayload("http://localhost/", "/submodel", ASSET_ID, "bpn") .get(5, TimeUnit.SECONDS) .getPayload(); @@ -289,7 +289,7 @@ void shouldReturnEmptyRelationshipsWhenRequestingWithNotExistingCatenaXIdAndSing new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)); // act - final String submodelResponse = testee.getSubmodelPayload("http://localhost/", "/submodel", ASSET_ID) + final String submodelResponse = testee.getSubmodelPayload("http://localhost/", "/submodel", ASSET_ID, "bpn") .get(5, TimeUnit.SECONDS) .getPayload(); @@ -311,7 +311,7 @@ void shouldReturnRawSerialPartWhenExisting() throws Exception { // act final String submodelResponse = testee.getSubmodelPayload("https://connector.endpoint.com", - "/shells/{aasIdentifier}/submodels/{submodelIdentifier}/submodel", ASSET_ID) + "/shells/{aasIdentifier}/submodels/{submodelIdentifier}/submodel", ASSET_ID, "bpn") .get(5, TimeUnit.SECONDS) .getPayload(); @@ -335,7 +335,7 @@ void shouldUseDecodedTargetId() throws Exception { // act final String submodelResponse = testee.getSubmodelPayload("https://connector.endpoint.com", - "/shells/{aasIdentifier}/submodels/{submodelIdentifier}/submodel", ASSET_ID) + "/shells/{aasIdentifier}/submodels/{submodelIdentifier}/submodel", ASSET_ID, "bpn") .get(5, TimeUnit.SECONDS) .getPayload(); @@ -359,7 +359,7 @@ void shouldReturnSameRelationshipsForDifferentDirections() throws Exception { // act final String relationshipsJson = testee.getSubmodelPayload("http://localhost/", "_singleLevelBomAsBuilt", - ASSET_ID).get(5, TimeUnit.SECONDS).getPayload(); + ASSET_ID, "bpn").get(5, TimeUnit.SECONDS).getPayload(); final var relationships = StringMapper.mapFromString(relationshipsJson, RelationshipAspect.from(asBuilt, Direction.DOWNWARD).getSubmodelClazz()).asRelationships(); @@ -372,7 +372,7 @@ void shouldReturnSameRelationshipsForDifferentDirections() throws Exception { prepareTestdata(childCatenaXId.getGlobalAssetId(), "_singleLevelUsageAsBuilt"); final String singleLevelUsageRelationshipsJson = testee.getSubmodelPayload("http://localhost/", - "_singleLevelUsageAsBuilt", ASSET_ID).get(5, TimeUnit.SECONDS).getPayload(); + "_singleLevelUsageAsBuilt", ASSET_ID, "bpn").get(5, TimeUnit.SECONDS).getPayload(); final var singleLevelUsageRelationships = StringMapper.mapFromString(singleLevelUsageRelationshipsJson, RelationshipAspect.from(asBuilt, Direction.UPWARD).getSubmodelClazz()).asRelationships(); @@ -395,7 +395,7 @@ void shouldRetrieveEndpointReferenceForAsset() throws Exception { when(catalogFacade.fetchCatalogByFilter(any(), any(), any())).thenReturn( List.of(CatalogItem.builder().itemId("asset-id").build())); when(contractNegotiationService.negotiate(any(), any(), - eq(new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)))).thenReturn( + eq(new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)), any())).thenReturn( NegotiationResponse.builder().contractAgreementId(agreementId).build()); final EndpointDataReference expected = mock(EndpointDataReference.class); when(endpointDataReferenceCacheService.getEndpointDataReferenceFromStorage(agreementId)).thenReturn( @@ -403,7 +403,7 @@ void shouldRetrieveEndpointReferenceForAsset() throws Exception { // act final var result = testee.getEndpointReferencesForAsset(ENDPOINT_ADDRESS, filterKey, filterValue, - new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)); + new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW), "bpn"); final EndpointDataReference actual = result.get(0).get(5, TimeUnit.SECONDS); // assert @@ -421,14 +421,14 @@ void shouldRetrieveEndpointReferenceForAsset2() throws Exception { when(catalogFacade.fetchCatalogByFilter(any(), any(), any())).thenReturn( List.of(CatalogItem.builder().itemId("asset-id").build())); when(contractNegotiationService.negotiate(any(), any(), - eq(new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)))).thenReturn( + eq(new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)), any())).thenReturn( NegotiationResponse.builder().contractAgreementId(agreementId).build()); final EndpointDataReference expected = mock(EndpointDataReference.class); when(endpointDataReferenceCacheService.getEndpointDataReferenceFromStorage(agreementId)).thenReturn( Optional.ofNullable(expected)); // act - final var result = testee.getEndpointReferencesForAsset(ENDPOINT_ADDRESS, filterKey, filterValue); + final var result = testee.getEndpointReferencesForAsset(ENDPOINT_ADDRESS, filterKey, filterValue, "bpn"); final EndpointDataReference actual = result.get(0).get(5, TimeUnit.SECONDS); // assert @@ -445,11 +445,11 @@ void shouldUseCachedEndpointReferenceValueWhenTokenIsValid() when(edcDataPlaneClient.getData(any(), any())).thenReturn(value); // act - final var resultFuture = testee.getSubmodelPayload(ENDPOINT_ADDRESS, "suffix", "assetId"); + final var resultFuture = testee.getSubmodelPayload(ENDPOINT_ADDRESS, "suffix", "assetId", "bpn"); // assert final String result = resultFuture.get().getPayload(); - verify(contractNegotiationService, never()).negotiate(any(), any(), any()); + verify(contractNegotiationService, never()).negotiate(any(), any(), any(), any()); assertThat(result).isEqualTo(value); } @@ -462,7 +462,7 @@ void shouldCreateCacheRecordWhenTokenIsNotValid() throws EdcClientException { when(catalogFacade.fetchCatalogByFilter(any(), any(), any())).thenReturn( List.of(CatalogItem.builder().itemId("itemId").build())); when(contractNegotiationService.negotiate(any(), any(), - eq(new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)))).thenReturn( + eq(new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)), any())).thenReturn( NegotiationResponse.builder().contractAgreementId(agreementId).build()); final EndpointDataReference ref = mock(EndpointDataReference.class); when(endpointDataReferenceCacheService.getEndpointDataReferenceFromStorage(agreementId)).thenReturn( @@ -471,7 +471,7 @@ void shouldCreateCacheRecordWhenTokenIsNotValid() throws EdcClientException { new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)); // act - testee.getSubmodelPayload(ENDPOINT_ADDRESS, "suffix", "assetId"); + testee.getSubmodelPayload(ENDPOINT_ADDRESS, "suffix", "assetId", "bpn"); // assert verify(endpointDataReferenceCacheService, times(1)).putEndpointDataReferenceIntoStorage("assetId", ref); @@ -482,13 +482,12 @@ private void prepareTestdata(final String catenaXId, final String submodelDataSu final String agreementId = "agreementId"; when(contractNegotiationService.negotiate(any(), any(), - eq(new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)))).thenReturn( + eq(new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW)), any())).thenReturn( NegotiationResponse.builder().contractAgreementId(agreementId).build()); final EndpointDataReference ref = TestMother.endpointDataReference(agreementId); when(endpointDataReferenceCacheService.getEndpointDataReferenceFromStorage(agreementId)).thenReturn( Optional.ofNullable(ref)); - final SubmodelTestdataCreator submodelTestdataCreator = new SubmodelTestdataCreator( localTestDataConfiguration.cxTestDataContainer()); final String data = StringMapper.mapToString( diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelFacadeTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelFacadeTest.java index 2c0b6884e7..95f81b1fc7 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelFacadeTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelFacadeTest.java @@ -76,11 +76,11 @@ void shouldThrowExecutionExceptionForSubmodel() throws EdcClientException { // arrange final ExecutionException e = new ExecutionException(new EdcClientException("test")); final CompletableFuture future = CompletableFuture.failedFuture(e); - when(client.getSubmodelPayload(any(), any(), any())).thenReturn(future); + when(client.getSubmodelPayload(any(), any(), any(), any())).thenReturn(future); // act ThrowableAssert.ThrowingCallable action = () -> testee.getSubmodelPayload(CONNECTOR_ENDPOINT, - SUBMODEL_SUFIX, ASSET_ID); + SUBMODEL_SUFIX, ASSET_ID, "bpn"); // assert assertThatThrownBy(action).isInstanceOf(EdcClientException.class); @@ -90,11 +90,11 @@ void shouldThrowExecutionExceptionForSubmodel() throws EdcClientException { void shouldThrowEdcClientExceptionForSubmodel() throws EdcClientException { // arrange final EdcClientException e = new EdcClientException("test"); - when(client.getSubmodelPayload(any(), any(), any())).thenThrow(e); + when(client.getSubmodelPayload(any(), any(), any(), any())).thenThrow(e); // act ThrowableAssert.ThrowingCallable action = () -> testee.getSubmodelPayload(CONNECTOR_ENDPOINT, - SUBMODEL_SUFIX, ASSET_ID); + SUBMODEL_SUFIX, ASSET_ID, "bpn"); // assert assertThatThrownBy(action).isInstanceOf(EdcClientException.class); @@ -107,10 +107,10 @@ void shouldRestoreInterruptOnInterruptExceptionForSubmodel() final CompletableFuture future = mock(CompletableFuture.class); final InterruptedException e = new InterruptedException(); when(future.get(config.getAsyncTimeoutMillis(), TimeUnit.MILLISECONDS)).thenThrow(e); - when(client.getSubmodelPayload(any(), any(), any())).thenReturn(future); + when(client.getSubmodelPayload(any(), any(), any(), any())).thenReturn(future); // act - testee.getSubmodelPayload(CONNECTOR_ENDPOINT, SUBMODEL_SUFIX, ASSET_ID); + testee.getSubmodelPayload(CONNECTOR_ENDPOINT, SUBMODEL_SUFIX, ASSET_ID, "bpn"); // assert assertThat(Thread.currentThread().isInterrupted()).isTrue(); @@ -129,10 +129,10 @@ void shouldRestoreInterruptOnInterruptExceptionForNotification() final CompletableFuture future = mock(CompletableFuture.class); final InterruptedException e = new InterruptedException(); when(future.get(config.getAsyncTimeoutMillis(), TimeUnit.MILLISECONDS)).thenThrow(e); - when(client.sendNotification(any(), any(), any())).thenReturn(future); + when(client.sendNotification(any(), any(), any(), any())).thenReturn(future); // act - testee.sendNotification("", "notify-request-asset", null); + testee.sendNotification("", "notify-request-asset", null, "bpn"); // assert assertThat(Thread.currentThread().isInterrupted()).isTrue(); @@ -143,10 +143,10 @@ void shouldThrowExecutionExceptionForNotification() throws EdcClientException { // arrange final ExecutionException e = new ExecutionException(new EdcClientException("test")); final CompletableFuture future = CompletableFuture.failedFuture(e); - when(client.sendNotification(any(), any(), any())).thenReturn(future); + when(client.sendNotification(any(), any(), any(), any())).thenReturn(future); // act - ThrowableAssert.ThrowingCallable action = () -> testee.sendNotification("", "notify-request-asset", null); + ThrowableAssert.ThrowingCallable action = () -> testee.sendNotification("", "notify-request-asset", null, "bpn"); // assert assertThatThrownBy(action).isInstanceOf(EdcClientException.class); @@ -156,10 +156,10 @@ void shouldThrowExecutionExceptionForNotification() throws EdcClientException { void shouldThrowEdcClientExceptionForNotification() throws EdcClientException { // arrange final EdcClientException e = new EdcClientException("test"); - when(client.sendNotification(any(), any(), any())).thenThrow(e); + when(client.sendNotification(any(), any(), any(), any())).thenThrow(e); // act - ThrowableAssert.ThrowingCallable action = () -> testee.sendNotification("", "notify-request-asset", null); + ThrowableAssert.ThrowingCallable action = () -> testee.sendNotification("", "notify-request-asset", null, "bpn"); // assert assertThatThrownBy(action).isInstanceOf(EdcClientException.class); @@ -174,10 +174,10 @@ class GetEndpointReferencesForAssetTests { void shouldThrowEdcClientExceptionForEndpointReference() throws EdcClientException { // arrange final EdcClientException e = new EdcClientException("test"); - when(client.getEndpointReferencesForAsset(any(), any(), any())).thenThrow(e); + when(client.getEndpointReferencesForAsset(any(), any(), any(), any())).thenThrow(e); // act - ThrowableAssert.ThrowingCallable action = () -> testee.getEndpointReferencesForAsset("", "", ""); + ThrowableAssert.ThrowingCallable action = () -> testee.getEndpointReferencesForAsset("", "", "", ""); // assert assertThatThrownBy(action).isInstanceOf(EdcClientException.class); @@ -187,12 +187,12 @@ void shouldThrowEdcClientExceptionForEndpointReference() throws EdcClientExcepti void shouldReturnFailedFuture() throws EdcClientException { // arrange - when(client.getEndpointReferencesForAsset(any(), any(), any())).thenReturn( + when(client.getEndpointReferencesForAsset(any(), any(), any(), any())).thenReturn( List.of(CompletableFuture.failedFuture(new EdcClientException("test")))); // act final List> results = testee.getEndpointReferencesForAsset("", "", - ""); + "", ""); // assert assertThat(results).hasSize(1); diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelFacadeWiremockTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelFacadeWiremockTest.java index 23510866e6..a7fafce3b5 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelFacadeWiremockTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelFacadeWiremockTest.java @@ -33,6 +33,7 @@ import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockSupport.PATH_DATAPLANE_PUBLIC; import static org.eclipse.tractusx.irs.testing.wiremock.WireMockConfig.responseWithStatus; import static org.eclipse.tractusx.irs.testing.wiremock.WireMockConfig.restTemplateProxy; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -131,7 +132,7 @@ void configureSystemUnderTest(WireMockRuntimeInfo wireMockRuntimeInfo) { storage); acceptedPoliciesProvider = mock(AcceptedPoliciesProvider.class); - when(acceptedPoliciesProvider.getAcceptedPolicies()).thenReturn(List.of(new AcceptedPolicy(policy("IRS Policy", + when(acceptedPoliciesProvider.getAcceptedPolicies("BPN")).thenReturn(List.of(new AcceptedPolicy(policy("IRS Policy", List.of(new Permission(PolicyType.USE, new Constraints( List.of(new Constraint("Membership", new Operator(OperatorType.EQ), "active"), new Constraint("FrameworkAgreement.traceability", new Operator(OperatorType.EQ), @@ -154,9 +155,18 @@ void shouldReturnAssemblyPartRelationshipAsString() givenThat(get(urlPathEqualTo(SUBMODEL_DATAPLANE_PATH)).willReturn( responseWithStatus(200).withBodyFile("singleLevelBomAsBuilt.json"))); + final List andConstraints = List.of( + new Constraint("Membership", new Operator(OperatorType.EQ), "active"), new Constraint("FrameworkAgreement.traceability", new Operator(OperatorType.EQ), "active")); + final ArrayList orConstraints = new ArrayList<>(); + final Permission permission = new Permission(PolicyType.USE, + new Constraints(andConstraints, orConstraints)); + final AcceptedPolicy acceptedPolicy = new AcceptedPolicy(policy("IRS Policy", List.of(permission)), + OffsetDateTime.now().plusYears(1)); + when(acceptedPoliciesProvider.getAcceptedPolicies(eq("bpn"))).thenReturn(List.of(acceptedPolicy)); + // Act final String submodel = edcSubmodelClient.getSubmodelPayload(CONNECTOR_ENDPOINT_URL, SUBMODEL_DATAPLANE_URL, - ASSET_ID).get().getPayload(); + ASSET_ID, "bpn").get().getPayload(); // Assert assertThat(submodel).contains("\"catenaXId\": \"urn:uuid:fe99da3d-b0de-4e80-81da-882aebcca978\""); @@ -170,9 +180,18 @@ void shouldReturnMaterialForRecyclingAsString() givenThat(get(urlPathEqualTo(SUBMODEL_DATAPLANE_PATH)).willReturn( responseWithStatus(200).withBodyFile("materialForRecycling.json"))); + final List andConstraints = List.of( + new Constraint("Membership", new Operator(OperatorType.EQ), "active"), new Constraint("FrameworkAgreement.traceability", new Operator(OperatorType.EQ), "active")); + final ArrayList orConstraints = new ArrayList<>(); + final Permission permission = new Permission(PolicyType.USE, + new Constraints(andConstraints, orConstraints)); + final AcceptedPolicy acceptedPolicy = new AcceptedPolicy(policy("IRS Policy", List.of(permission)), + OffsetDateTime.now().plusYears(1)); + when(acceptedPoliciesProvider.getAcceptedPolicies(eq("bpn"))).thenReturn(List.of(acceptedPolicy)); + // Act final String submodel = edcSubmodelClient.getSubmodelPayload(CONNECTOR_ENDPOINT_URL, SUBMODEL_DATAPLANE_URL, - ASSET_ID).get().getPayload(); + ASSET_ID, "bpn").get().getPayload(); // Assert assertThat(submodel).contains("\"materialName\": \"Cooper\","); @@ -185,9 +204,18 @@ void shouldReturnObjectAsStringWhenResponseNotJSON() prepareNegotiation(); givenThat(get(urlPathEqualTo(SUBMODEL_DATAPLANE_PATH)).willReturn(responseWithStatus(200).withBody("test"))); + final List andConstraints = List.of( + new Constraint("Membership", new Operator(OperatorType.EQ), "active"), new Constraint("FrameworkAgreement.traceability", new Operator(OperatorType.EQ), "active")); + final ArrayList orConstraints = new ArrayList<>(); + final Permission permission = new Permission(PolicyType.USE, + new Constraints(andConstraints, orConstraints)); + final AcceptedPolicy acceptedPolicy = new AcceptedPolicy(policy("IRS Policy", List.of(permission)), + OffsetDateTime.now().plusYears(1)); + when(acceptedPoliciesProvider.getAcceptedPolicies(eq("bpn"))).thenReturn(List.of(acceptedPolicy)); + // Act final String submodel = edcSubmodelClient.getSubmodelPayload(CONNECTOR_ENDPOINT_URL, SUBMODEL_DATAPLANE_URL, - ASSET_ID).get().getPayload(); + ASSET_ID, "bpn").get().getPayload(); // Assert assertThat(submodel).isEqualTo("test"); @@ -203,7 +231,7 @@ void shouldThrowExceptionWhenPoliciesAreNotAccepted() { final AcceptedPolicy acceptedPolicy = new AcceptedPolicy(policy("IRS Policy", List.of(permission)), OffsetDateTime.now().plusYears(1)); - when(acceptedPoliciesProvider.getAcceptedPolicies()).thenReturn(List.of(acceptedPolicy)); + when(acceptedPoliciesProvider.getAcceptedPolicies("bpn")).thenReturn(List.of(acceptedPolicy)); prepareNegotiation(); givenThat(get(urlPathEqualTo(SUBMODEL_DATAPLANE_PATH)).willReturn(responseWithStatus(200).withBody("test"))); @@ -211,7 +239,7 @@ void shouldThrowExceptionWhenPoliciesAreNotAccepted() { // Act & Assert final String errorMessage = "Consumption of asset '58505404-4da1-427a-82aa-b79482bcd1f0' is not permitted as the required catalog offer policies do not comply with defined IRS policies."; assertThatExceptionOfType(UsagePolicyException.class).isThrownBy( - () -> edcSubmodelClient.getSubmodelPayload(CONNECTOR_ENDPOINT_URL, SUBMODEL_DATAPLANE_URL, ASSET_ID) + () -> edcSubmodelClient.getSubmodelPayload(CONNECTOR_ENDPOINT_URL, SUBMODEL_DATAPLANE_URL, ASSET_ID, "bpn") .get()).withMessageEndingWith(errorMessage); } @@ -222,9 +250,18 @@ void shouldThrowExceptionWhenResponse_400() { givenThat(get(urlPathEqualTo(SUBMODEL_DATAPLANE_PATH)).willReturn( responseWithStatus(400).withBody("{ error: '400'}"))); + final List andConstraints = List.of( + new Constraint("Membership", new Operator(OperatorType.EQ), "active"), new Constraint("FrameworkAgreement.traceability", new Operator(OperatorType.EQ), "active")); + final ArrayList orConstraints = new ArrayList<>(); + final Permission permission = new Permission(PolicyType.USE, + new Constraints(andConstraints, orConstraints)); + final AcceptedPolicy acceptedPolicy = new AcceptedPolicy(policy("IRS Policy", List.of(permission)), + OffsetDateTime.now().plusYears(1)); + when(acceptedPoliciesProvider.getAcceptedPolicies(eq("bpn"))).thenReturn(List.of(acceptedPolicy)); + // Act final ThrowableAssert.ThrowingCallable throwingCallable = () -> edcSubmodelClient.getSubmodelPayload( - CONNECTOR_ENDPOINT_URL, SUBMODEL_DATAPLANE_URL, ASSET_ID).get(5, TimeUnit.SECONDS); + CONNECTOR_ENDPOINT_URL, SUBMODEL_DATAPLANE_URL, ASSET_ID, "bpn").get(5, TimeUnit.SECONDS); // Assert assertThatExceptionOfType(ExecutionException.class).isThrownBy(throwingCallable) @@ -238,9 +275,18 @@ void shouldThrowExceptionWhenResponse_500() { givenThat(get(urlPathEqualTo(SUBMODEL_DATAPLANE_PATH)).willReturn( responseWithStatus(500).withBody("{ error: '500'}"))); + final List andConstraints = List.of( + new Constraint("Membership", new Operator(OperatorType.EQ), "active"), new Constraint("FrameworkAgreement.traceability", new Operator(OperatorType.EQ), "active")); + final ArrayList orConstraints = new ArrayList<>(); + final Permission permission = new Permission(PolicyType.USE, + new Constraints(andConstraints, orConstraints)); + final AcceptedPolicy acceptedPolicy = new AcceptedPolicy(policy("IRS Policy", List.of(permission)), + OffsetDateTime.now().plusYears(1)); + when(acceptedPoliciesProvider.getAcceptedPolicies(eq("bpn"))).thenReturn(List.of(acceptedPolicy)); + // Act final ThrowableAssert.ThrowingCallable throwingCallable = () -> edcSubmodelClient.getSubmodelPayload( - CONNECTOR_ENDPOINT_URL, SUBMODEL_DATAPLANE_URL, ASSET_ID).get(5, TimeUnit.SECONDS); + CONNECTOR_ENDPOINT_URL, SUBMODEL_DATAPLANE_URL, ASSET_ID, "bpn").get(5, TimeUnit.SECONDS); // Assert assertThatExceptionOfType(ExecutionException.class).isThrownBy(throwingCallable) diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelRetryerTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelRetryerTest.java index 75e33e15c4..a3105d789b 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelRetryerTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelRetryerTest.java @@ -100,7 +100,7 @@ void shouldRetryExecutionOfGetSubmodelOnClientMaxAttemptTimes() { // Act assertThatThrownBy(() -> testee.getSubmodelPayload("https://connector.endpoint.com", "/shells/{aasIdentifier}/submodels/{submodelIdentifier}/submodel", - "9300395e-c0a5-4e88-bc57-a3973fec4c26")).hasCauseInstanceOf(HttpServerErrorException.class); + "9300395e-c0a5-4e88-bc57-a3973fec4c26", "bpn")).hasCauseInstanceOf(HttpServerErrorException.class); // Assert verify(restTemplate, times(retryRegistry.getDefaultConfig().getMaxAttempts())).exchange(any(String.class), @@ -119,7 +119,7 @@ void shouldRetryOnAnyRuntimeException() { // Act assertThatThrownBy(() -> testee.getSubmodelPayload("https://connector.endpoint.com", "/shells/{aasIdentifier}/submodels/{submodelIdentifier}/submodel", - "9300395e-c0a5-4e88-bc57-a3973fec4c26")).hasCauseInstanceOf(RuntimeException.class); + "9300395e-c0a5-4e88-bc57-a3973fec4c26", "bpn")).hasCauseInstanceOf(RuntimeException.class); // Assert verify(restTemplate, times(retryRegistry.getDefaultConfig().getMaxAttempts())).exchange(any(String.class), diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/AcceptedPoliciesProviderTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/AcceptedPoliciesProviderTest.java index a0d042703f..e572a6a2da 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/AcceptedPoliciesProviderTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/AcceptedPoliciesProviderTest.java @@ -37,7 +37,7 @@ class AcceptedPoliciesProviderTest { @Test void getAcceptedPolicies() { - final var acceptedPolicies = testee.getAcceptedPolicies(); + final var acceptedPolicies = testee.getAcceptedPolicies("testBpn"); assertThat(acceptedPolicies).isEmpty(); } @@ -45,20 +45,20 @@ void getAcceptedPolicies() { @Test void shouldReturnStoredPolicies() { testee.addAcceptedPolicies(List.of(policy())); - final var acceptedPolicies = testee.getAcceptedPolicies(); + final var acceptedPolicies = testee.getAcceptedPolicies("testBpn"); assertThat(acceptedPolicies).hasSize(1); } @Test void shouldRemoveStoredPolicies() { testee.addAcceptedPolicies(List.of(policy())); - final var acceptedPolicies = testee.getAcceptedPolicies(); + final var acceptedPolicies = testee.getAcceptedPolicies("testBpn"); assertThat(acceptedPolicies).hasSize(1); testee.removeAcceptedPolicies(acceptedPolicies); - assertThat(testee.getAcceptedPolicies()).isEmpty(); + assertThat(testee.getAcceptedPolicies("testBpn")).isEmpty(); } @NotNull private static AcceptedPolicy policy() { diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerServiceTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerServiceTest.java index 1954360597..d3d5de037e 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerServiceTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerServiceTest.java @@ -29,6 +29,7 @@ import static org.eclipse.tractusx.irs.edc.client.testutil.TestMother.createAtomicConstraintPolicy; import static org.eclipse.tractusx.irs.edc.client.testutil.TestMother.createOrConstraintPolicy; import static org.eclipse.tractusx.irs.edc.client.testutil.TestMother.createXOneConstraintPolicy; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import java.time.OffsetDateTime; @@ -52,11 +53,6 @@ class PolicyCheckerServiceTest { @BeforeEach void setUp() { - final var policyList = List.of( - new AcceptedPolicy(policy(TestConstants.ID_3_0_TRACE), OffsetDateTime.now().plusYears(1)), - new AcceptedPolicy(policy(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY), - OffsetDateTime.now().plusYears(1))); - when(policyStore.getAcceptedPolicies()).thenReturn(policyList); policyCheckerService = new PolicyCheckerService(policyStore, new ConstraintCheckerService()); } @@ -66,7 +62,7 @@ void shouldRejectWrongPolicy() { final String unknownRightExpression = "Wrong_Trace"; Policy policy = createAtomicConstraintPolicy(TestConstants.PURPOSE, unknownRightExpression); // when - boolean result = policyCheckerService.isValid(policy); + boolean result = policyCheckerService.isValid(policy, "bpn"); // then assertThat(result).isFalse(); @@ -76,9 +72,9 @@ void shouldRejectWrongPolicy() { void shouldRejectWhenPolicyStoreIsEmpty() { // given Policy policy = createAtomicConstraintPolicy(TestConstants.PURPOSE, TestConstants.ID_3_0_TRACE); - when(policyStore.getAcceptedPolicies()).thenReturn(List.of()); + when(policyStore.getAcceptedPolicies(any())).thenReturn(List.of()); // when - boolean result = policyCheckerService.isValid(policy); + boolean result = policyCheckerService.isValid(policy, "bpn"); // then assertThat(result).isFalse(); @@ -91,13 +87,13 @@ void shouldRejectAndConstraintsWhenOnlyOneMatch() { OffsetDateTime.now().plusYears(1)), new AcceptedPolicy(policy(TestConstants.FRAMEWORK_AGREEMENT_DISMANTLER), OffsetDateTime.now().plusYears(1))); - when(policyStore.getAcceptedPolicies()).thenReturn(policyList); + when(policyStore.getAcceptedPolicies(any())).thenReturn(policyList); Policy policy = createAndConstraintPolicy( List.of(createAtomicConstraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, TestConstants.STATUS_ACTIVE), createAtomicConstraint(TestConstants.MEMBERSHIP, TestConstants.STATUS_ACTIVE))); // when - boolean result = policyCheckerService.isValid(policy); + boolean result = policyCheckerService.isValid(policy, "bpn"); // then assertThat(result).isFalse(); @@ -116,13 +112,13 @@ void shouldAcceptAndConstraintsWhenAcceptedPolicyContainsMoreConstraintsSuperSet new AcceptedPolicy(policy("and-policy", List.of(constraint1, constraint2, constraint3), List.of()), OffsetDateTime.now().plusYears(1))); - when(policyStore.getAcceptedPolicies()).thenReturn(policyList); + when(policyStore.getAcceptedPolicies(any())).thenReturn(policyList); Policy policy = createAndConstraintPolicy( List.of(createAtomicConstraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, TestConstants.STATUS_ACTIVE), createAtomicConstraint(TestConstants.MEMBERSHIP, TestConstants.STATUS_ACTIVE))); // when - boolean result = policyCheckerService.isValid(policy); + boolean result = policyCheckerService.isValid(policy, "bpn"); // then assertThat(result).isTrue(); @@ -141,13 +137,13 @@ void shouldAcceptOrConstraintsWhenAcceptedPolicyContainsMoreConstraintsSuperSetO new AcceptedPolicy(policy("and-policy", List.of(), List.of(constraint1, constraint2, constraint3)), OffsetDateTime.now().plusYears(1))); - when(policyStore.getAcceptedPolicies()).thenReturn(policyList); + when(policyStore.getAcceptedPolicies(any())).thenReturn(policyList); Policy policy = createOrConstraintPolicy( List.of(createAtomicConstraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, TestConstants.STATUS_ACTIVE), createAtomicConstraint(TestConstants.MEMBERSHIP, TestConstants.STATUS_ACTIVE))); // when - boolean result = policyCheckerService.isValid(policy); + boolean result = policyCheckerService.isValid(policy, "bpn"); // then assertThat(result).isTrue(); @@ -166,14 +162,14 @@ void shouldAcceptConstraintsWithDefaultPolicy() { final var policyList = List.of(new AcceptedPolicy( policy("default-policy", List.of(constraint1, constraint2, constraint3), List.of(constraint1, constraint2, constraint3)), OffsetDateTime.now().plusYears(1))); - when(policyStore.getAcceptedPolicies()).thenReturn(policyList); + when(policyStore.getAcceptedPolicies(any())).thenReturn(policyList); Policy policy = createOrConstraintPolicy( List.of(createAtomicConstraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, TestConstants.STATUS_ACTIVE), createAtomicConstraint(TestConstants.MEMBERSHIP, TestConstants.STATUS_ACTIVE))); // when - boolean result = policyCheckerService.isValid(policy); + boolean result = policyCheckerService.isValid(policy, "bpn"); // then assertThat(result).isTrue(); @@ -186,13 +182,13 @@ void shouldRejectOrConstraintsWhenNoneMatch() { new AcceptedPolicy(policy(TestConstants.FRAMEWORK_AGREEMENT_TEST), OffsetDateTime.now().plusYears(1)), new AcceptedPolicy(policy(TestConstants.FRAMEWORK_AGREEMENT_DISMANTLER), OffsetDateTime.now().plusYears(1))); - when(policyStore.getAcceptedPolicies()).thenReturn(policyList); + when(policyStore.getAcceptedPolicies(any())).thenReturn(policyList); Policy policy = createAndConstraintPolicy( List.of(createAtomicConstraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, TestConstants.STATUS_ACTIVE), createAtomicConstraint(TestConstants.MEMBERSHIP, TestConstants.STATUS_ACTIVE))); // when - boolean result = policyCheckerService.isValid(policy); + boolean result = policyCheckerService.isValid(policy, "bpn"); // then assertThat(result).isFalse(); @@ -205,13 +201,13 @@ void shouldRejectXOneConstraintsWhenNoneMatch() { new AcceptedPolicy(policy(TestConstants.FRAMEWORK_AGREEMENT_TEST), OffsetDateTime.now().plusYears(1)), new AcceptedPolicy(policy(TestConstants.FRAMEWORK_AGREEMENT_DISMANTLER), OffsetDateTime.now().plusYears(1))); - when(policyStore.getAcceptedPolicies()).thenReturn(policyList); + when(policyStore.getAcceptedPolicies(any())).thenReturn(policyList); Policy policy = createXOneConstraintPolicy( List.of(createAtomicConstraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, TestConstants.STATUS_ACTIVE), createAtomicConstraint(TestConstants.MEMBERSHIP, TestConstants.STATUS_ACTIVE))); // when - boolean result = policyCheckerService.isValid(policy); + boolean result = policyCheckerService.isValid(policy, "bpn"); // then assertThat(result).isFalse(); @@ -223,13 +219,13 @@ void shouldRejectXOneConstraintsWhenMoreThanOneMatch() { final var policyList = List.of(new AcceptedPolicy(policy(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY), OffsetDateTime.now().plusYears(1)), new AcceptedPolicy(policy(TestConstants.MEMBERSHIP), OffsetDateTime.now().plusYears(1))); - when(policyStore.getAcceptedPolicies()).thenReturn(policyList); + when(policyStore.getAcceptedPolicies(any())).thenReturn(policyList); Policy policy = createXOneConstraintPolicy( List.of(createAtomicConstraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, TestConstants.STATUS_ACTIVE), createAtomicConstraint(TestConstants.MEMBERSHIP, TestConstants.STATUS_ACTIVE))); // when - boolean result = policyCheckerService.isValid(policy); + boolean result = policyCheckerService.isValid(policy, "bpn"); // then assertThat(result).isFalse(); diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java index 56aa0e1b72..1caf0a65aa 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java @@ -27,6 +27,11 @@ import static org.eclipse.tractusx.irs.common.ApiConstants.UNAUTHORIZED_DESC; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import java.util.AbstractMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; @@ -36,7 +41,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.validation.Valid; -import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.irs.common.auth.IrsRoles; @@ -56,6 +60,7 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @@ -67,17 +72,18 @@ @RequestMapping("irs") @RequiredArgsConstructor @SuppressWarnings({ "PMD.AvoidDuplicateLiterals", - "PMD.ExcessiveImports" + "PMD.ExcessiveImports", + "PMD.UseVarargs" }) public class PolicyStoreController { private final PolicyStoreService service; private final EdcTransformer edcTransformer; + private static final String DEFAULT = "default"; @Operation(operationId = "registerAllowedPolicy", summary = "Register a policy that should be accepted in EDC negotiation.", - security = @SecurityRequirement(name = "api_key"), - tags = { "Item Relationship Service" }, + security = @SecurityRequirement(name = "api_key"), tags = { "Item Relationship Service" }, description = "Register a policy that should be accepted in EDC negotiation.") @ApiResponses(value = { @ApiResponse(responseCode = "201"), @ApiResponse(responseCode = "400", description = "Policy registration failed.", @@ -99,19 +105,25 @@ public class PolicyStoreController { ref = "#/components/examples/error-response-403")) }), }) + @PostMapping("/policies") @ResponseStatus(HttpStatus.CREATED) @PreAuthorize("hasAuthority('" + IrsRoles.ADMIN_IRS + "')") public void registerAllowedPolicy(final @RequestBody CreatePolicyRequest request) { - final Policy policy = edcTransformer.transformToPolicy(request.payload()); - policy.setValidUntil(request.validUntil()); - service.registerPolicy(policy); + request.payload() + .stream() + .map(payload -> { + final Policy policy = edcTransformer.transformToPolicy(payload); + policy.setValidUntil(request.validUntil()); + return policy; + }) + .forEach(policy -> service.registerPolicy(policy, + request.businessPartnerNumbers() == null ? List.of(DEFAULT) : request.businessPartnerNumbers())); } - @Operation(operationId = "getAllowedPolicies", + @Operation(operationId = "getAllowedPoliciesByBpn", summary = "Lists the registered policies that should be accepted in EDC negotiation.", - security = @SecurityRequirement(name = "api_key"), - tags = { "Item Relationship Service" }, + security = @SecurityRequirement(name = "api_key"), tags = { "Item Relationship Service" }, description = "Lists the registered policies that should be accepted in EDC negotiation.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Returns the policies.", content = { @Content(mediaType = APPLICATION_JSON_VALUE, array = @ArraySchema( @@ -133,16 +145,18 @@ public void registerAllowedPolicy(final @RequestBody CreatePolicyRequest request @GetMapping("/policies") @ResponseStatus(HttpStatus.OK) @PreAuthorize("hasAuthority('" + IrsRoles.ADMIN_IRS + "')") - public List getPolicies() { - return service.getStoredPolicies().stream() - .map(PolicyResponse::fromPolicy) - .toList(); + public Map> getPolicies(@RequestParam(required = false) final List bpnls) { + return service.getPolicies(bpnls) + .entrySet() + .stream() + .map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey(), + entry.getValue().stream().map(PolicyResponse::fromPolicy).toList())) + .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)); } @Operation(operationId = "deleteAllowedPolicy", summary = "Removes a policy that should no longer be accepted in EDC negotiation.", - security = @SecurityRequirement(name = "api_key"), - tags = { "Item Relationship Service" }, + security = @SecurityRequirement(name = "api_key"), tags = { "Item Relationship Service" }, description = "Removes a policy that should no longer be accepted in EDC negotiation.") @ApiResponses(value = { @ApiResponse(responseCode = "200"), @ApiResponse(responseCode = "400", description = "Policy deletion failed.", @@ -171,10 +185,9 @@ public void deleteAllowedPolicy(@PathVariable("policyId") final String policyId) service.deletePolicy(policyId); } - @Operation(operationId = "updateAllowedPolicy", summary = "Updates an existing policy with new validUntil value.", - security = @SecurityRequirement(name = "api_key"), - tags = { "Item Relationship Service" }, - description = "Updates an existing policy with new validUntil value.") + @Operation(operationId = "updateAllowedPolicy", summary = "Updates an existing policy.", + security = @SecurityRequirement(name = "api_key"), tags = { "Item Relationship Service" }, + description = "Updates an existing policy.") @ApiResponses(value = { @ApiResponse(responseCode = "200"), @ApiResponse(responseCode = "400", description = "Policy update failed.", content = { @Content(mediaType = APPLICATION_JSON_VALUE, @@ -195,11 +208,11 @@ public void deleteAllowedPolicy(@PathVariable("policyId") final String policyId) ref = "#/components/examples/error-response-403")) }), }) - @PutMapping("/policies/{policyId}") + @PutMapping("/policies") @ResponseStatus(HttpStatus.OK) @PreAuthorize("hasAuthority('" + IrsRoles.ADMIN_IRS + "')") - public void updateAllowedPolicy(@PathVariable("policyId") final String policyId, - final @Valid @RequestBody UpdatePolicyRequest request) { - service.updatePolicy(policyId, request); + public void updateAllowedPolicy(final @Valid @RequestBody UpdatePolicyRequest request) { + service.updatePolicies(request); } + } diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/models/CreatePolicyRequest.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/models/CreatePolicyRequest.java index 06fbee3f36..3154a363ee 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/models/CreatePolicyRequest.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/models/CreatePolicyRequest.java @@ -24,7 +24,9 @@ package org.eclipse.tractusx.irs.policystore.models; import java.time.OffsetDateTime; +import java.util.List; +import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.json.JsonObject; import jakarta.validation.constraints.NotNull; @@ -36,7 +38,8 @@ @Schema(description = "Request to add a policy") public record CreatePolicyRequest( @NotNull @Schema(description = "Timestamp after which the policy will no longer be accepted in negotiations") OffsetDateTime validUntil, - @NotNull @Schema(example = CreatePolicyRequest.EXAMPLE_PAYLOAD) JsonObject payload) { + @ArraySchema() List businessPartnerNumbers, + @NotNull @Schema(example = CreatePolicyRequest.EXAMPLE_PAYLOAD) List payload) { @SuppressWarnings("java:S2479") // this value is used by open-api to show example payload diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/models/UpdatePolicyRequest.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/models/UpdatePolicyRequest.java index 4b4c455bd3..ead5a738bc 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/models/UpdatePolicyRequest.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/models/UpdatePolicyRequest.java @@ -24,6 +24,7 @@ package org.eclipse.tractusx.irs.policystore.models; import java.time.OffsetDateTime; +import java.util.List; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; @@ -33,5 +34,7 @@ */ @Schema(description = "Request to add a policy") public record UpdatePolicyRequest( - @Schema(description = "Timestamp after which the policy will no longer be accepted in negotiations") @NotNull OffsetDateTime validUntil) { + @Schema(description = "Timestamp after which the policy will no longer be accepted in negotiations") @NotNull OffsetDateTime validUntil, + List businessPartnerNumbers, + List policiesIds) { } diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/persistence/PolicyPersistence.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/persistence/PolicyPersistence.java index b2991563c5..84a92b6316 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/persistence/PolicyPersistence.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/persistence/PolicyPersistence.java @@ -26,11 +26,13 @@ import static org.eclipse.tractusx.irs.policystore.config.PolicyConfiguration.POLICY_BLOB_PERSISTENCE; import java.io.IOException; -import java.time.OffsetDateTime; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -60,19 +62,29 @@ public class PolicyPersistence { */ private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + private static final String COULD_NOT_READ_POLICY_ERROR_MESSAGE = "Could not read the policies from the store"; + public PolicyPersistence(@Qualifier(POLICY_BLOB_PERSISTENCE) final BlobPersistence policyStorePersistence, final ObjectMapper mapper) { this.policyStorePersistence = policyStorePersistence; this.mapper = mapper; } - public void save(final String bpn, final Policy policy) { - final var policies = readAll(bpn); + public void save(final List bpns, final Policy policy) { + final Map> storedBpnToPolicies = bpns.stream() + .collect(Collectors.toMap(bpn -> bpn, + this::readAll)); + storedBpnToPolicies.forEach((bpn, policies) -> { + checkIfPolicyAlreadyExists(policy, policies); + policies.add(policy); + save(bpn, policies); + }); + } + + private static void checkIfPolicyAlreadyExists(final Policy policy, final List policies) { if (policies.stream().map(Policy::getPolicyId).anyMatch(policy.getPolicyId()::equals)) { throw new PolicyStoreException("Policy with id '" + policy.getPolicyId() + "' already exists!"); } - policies.add(policy); - save(bpn, policies); } public void delete(final String bpn, final String policyId) { @@ -84,18 +96,6 @@ public void delete(final String bpn, final String policyId) { save(bpn, modifiedPolicies); } - public void update(final String bpn, final String policyId, final OffsetDateTime validUntil) { - final var policies = readAll(bpn); - final Policy policy = policies.stream() - .filter(p -> p.getPolicyId().equals(policyId)) - .findFirst() - .orElseThrow(() -> new PolicyStoreException( - "Policy with id '" + policyId + "' doesn't exists!")); - - policy.update(validUntil); - save(bpn, policies); - } - private void save(final String bpn, final List modifiedPolicies) { writeLock(() -> { try { @@ -113,7 +113,7 @@ public List readAll(final String bpn) { try { return mapper.readerForListOf(Policy.class).>readValue(blob); } catch (IOException | RuntimeException e) { - throw new PolicyStoreException("Could not read the policies from the store", e); + throw new PolicyStoreException(COULD_NOT_READ_POLICY_ERROR_MESSAGE, e); } }).map(ArrayList::new).orElseGet(ArrayList::new); @@ -123,6 +123,27 @@ public List readAll(final String bpn) { } + /** + * Returns all policies. + * + * @return policies as map of BPN to list of policies + */ + public Map> readAll() { + try { + return policyStorePersistence.getAllBlobs().entrySet().stream().map(entry -> { + try { + final String bpn = entry.getKey(); + return new AbstractMap.SimpleEntry<>(bpn, + mapper.readerForListOf(Policy.class).>readValue(entry.getValue())); + } catch (IOException e) { + throw new PolicyStoreException(COULD_NOT_READ_POLICY_ERROR_MESSAGE, e); + } + }).collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)); + } catch (BlobPersistenceException e) { + throw new PolicyStoreException(COULD_NOT_READ_POLICY_ERROR_MESSAGE, e); + } + } + private void writeLock(final Runnable work) { try { if (!lock.writeLock().tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) { diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyHelper.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyHelper.java new file mode 100644 index 0000000000..98fa17fecf --- /dev/null +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyHelper.java @@ -0,0 +1,48 @@ +/******************************************************************************** + * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +package org.eclipse.tractusx.irs.policystore.services; + +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; + +import org.eclipse.tractusx.irs.edc.client.policy.Policy; + +/** + * Helper methods for policies. + */ +public final class PolicyHelper { + + private PolicyHelper() { + } + + public static List findBpnsByPolicyId(final Map> policyMap, final String policyId) { + return policyMap.entrySet().stream().filter(mapEntriesByPolicyId(policyId)).map(Map.Entry::getKey).toList(); + } + + private static Predicate>> mapEntriesByPolicyId(final String policyId) { + return entry -> entry.getValue().stream().anyMatch(havingPolicyId(policyId)); + } + + public static Predicate havingPolicyId(final String policyId) { + return policy -> policy.getPolicyId().equals(policyId); + } + +} diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreService.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreService.java index 3f16e4a90b..725bfd4d97 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreService.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreService.java @@ -23,10 +23,19 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.policystore.services; +import static org.eclipse.tractusx.irs.common.persistence.BlobPersistence.DEFAULT_BLOB_NAME; + import java.time.Clock; import java.time.OffsetDateTime; +import java.util.AbstractMap; import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.TreeSet; +import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.irs.edc.client.policy.AcceptedPoliciesProvider; @@ -42,7 +51,6 @@ import org.eclipse.tractusx.irs.policystore.exceptions.PolicyStoreException; import org.eclipse.tractusx.irs.policystore.models.UpdatePolicyRequest; import org.eclipse.tractusx.irs.policystore.persistence.PolicyPersistence; -import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; @@ -55,26 +63,25 @@ public class PolicyStoreService implements AcceptedPoliciesProvider { public static final int DEFAULT_POLICY_LIFETIME_YEARS = 5; - private final String apiAllowedBpn; private final List allowedPoliciesFromConfig; private final PolicyPersistence persistence; private final Clock clock; private static final String MISSING_REQUEST_FIELD_MESSAGE = "Request does not contain all required fields. Missing: %s"; + private static final String DEFAULT = "default"; - public PolicyStoreService(@Value("${apiAllowedBpn:}") final String apiAllowedBpn, - final DefaultAcceptedPoliciesConfig defaultAcceptedPoliciesConfig, final PolicyPersistence persistence, final Clock clock) { - this.apiAllowedBpn = apiAllowedBpn; + public PolicyStoreService(final DefaultAcceptedPoliciesConfig defaultAcceptedPoliciesConfig, + final PolicyPersistence persistence, final Clock clock) { this.allowedPoliciesFromConfig = createDefaultPolicyFromConfig(defaultAcceptedPoliciesConfig); this.persistence = persistence; this.clock = clock; } - public void registerPolicy(final Policy policy) { + public void registerPolicy(final Policy policy, final List businessPartnersNumbers) { validatePolicy(policy); policy.setCreatedOn(OffsetDateTime.now(clock)); log.info("Registering new policy with id {}, valid until {}", policy.getPolicyId(), policy.getValidUntil()); try { - persistence.save(apiAllowedBpn, policy); + persistence.save(businessPartnersNumbers, policy); } catch (final PolicyStoreException e) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage(), e); } @@ -82,20 +89,35 @@ public void registerPolicy(final Policy policy) { /** * Checks whether policy from register policy request has all required fields + * * @param policy policy to register */ private void validatePolicy(final Policy policy) { + if (policy.getPermissions() == null) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, String.format(MISSING_REQUEST_FIELD_MESSAGE, "odrl:permission")); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, + String.format(MISSING_REQUEST_FIELD_MESSAGE, "odrl:permission")); } + if (policy.getPermissions().stream().anyMatch(p -> p.getConstraint() == null)) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, String.format(MISSING_REQUEST_FIELD_MESSAGE, "odrl:constraint")); + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, + String.format(MISSING_REQUEST_FIELD_MESSAGE, "odrl:constraint")); + } + } + + public Map> getPolicies(final List bpns) { + if (bpns == null) { + return getAllStoredPolicies(); + } else { + return bpns.stream().map(bpn -> new AbstractMap.SimpleEntry<>(bpn, getStoredPolicies(List.of(bpn)))).collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)); } } - public List getStoredPolicies() { - log.info("Reading all stored polices for BPN {}", apiAllowedBpn); - final var storedPolicies = persistence.readAll(apiAllowedBpn); + public List getStoredPolicies(final List bpns) { + log.info("Reading all stored polices for BPN {}", bpns); + final List storedPolicies = new LinkedList<>(); + bpns.forEach(bpn -> storedPolicies.addAll(persistence.readAll(bpn))); + if (storedPolicies.isEmpty()) { log.info("Policy store is empty, returning default values from config"); return allowedPoliciesFromConfig; @@ -104,28 +126,76 @@ public List getStoredPolicies() { } } + public Map> getAllStoredPolicies() { + final Map> bpnToPolicies = persistence.readAll(); + if (bpnToPolicies.isEmpty()) { + return Map.of("", allowedPoliciesFromConfig); + } + return bpnToPolicies; + } + public void deletePolicy(final String policyId) { try { + log.info("Getting all policies to find correct bpn number"); + final List bpnsContainingPolicyId = PolicyHelper.findBpnsByPolicyId(getAllStoredPolicies(), + policyId); + log.info("Deleting policy with id {}", policyId); - persistence.delete(apiAllowedBpn, policyId); + bpnsContainingPolicyId.forEach(bpn -> persistence.delete(bpn, policyId)); } catch (final PolicyStoreException e) { throw new ResponseStatusException(HttpStatus.NOT_FOUND, e.getMessage(), e); } } - public void updatePolicy(final String policyId, final UpdatePolicyRequest request) { + public void updatePolicies(final UpdatePolicyRequest request) { + for (final String policyId : request.policiesIds()) { + updatePolicy(policyId, request.validUntil(), request.businessPartnerNumbers() == null ? List.of(DEFAULT) : request.businessPartnerNumbers()); + } + } + + public void updatePolicy(final String policyId, final OffsetDateTime validUntil, final List bpns) { try { log.info("Updating policy with id {}", policyId); - persistence.update(apiAllowedBpn, policyId, request.validUntil()); + final List bpnsContainingPolicyId = PolicyHelper.findBpnsByPolicyId(getAllStoredPolicies(), + policyId); + + final Policy policyToUpdate = getStoredPolicies(bpnsContainingPolicyId).stream() + .filter(PolicyHelper.havingPolicyId( + policyId)) + .findAny() + .orElseThrow( + () -> new PolicyStoreException( + "Policy with id '" + + policyId + + "' doesn't exists!")); + + policyToUpdate.update(validUntil); + bpnsContainingPolicyId.forEach(bpn -> persistence.delete(bpn, policyId)); + persistence.save(bpns, policyToUpdate); } catch (final PolicyStoreException e) { throw new ResponseStatusException(HttpStatus.NOT_FOUND, e.getMessage(), e); } } @Override - public List getAcceptedPolicies() { - return getStoredPolicies().stream().map(this::toAcceptedPolicy).toList(); + public List getAcceptedPolicies(final String bpn) { + if (bpn == null) { + return getAllStoredPolicies().values() + .stream() + .flatMap(Collection::stream) + .map(this::toAcceptedPolicy) + .toList(); + } + + final ArrayList policies = new ArrayList<>(); + policies.addAll(getStoredPolicies(List.of(bpn))); + policies.addAll(getStoredPolicies(List.of(DEFAULT_BLOB_NAME))); + + final TreeSet result = new TreeSet<>(Comparator.comparing(Policy::getPolicyId)); + result.addAll(policies); + + return result.stream().map(this::toAcceptedPolicy).toList(); } private AcceptedPolicy toAcceptedPolicy(final Policy policy) { diff --git a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreControllerTest.java b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreControllerTest.java index f685cd33ab..b504e5bdab 100644 --- a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreControllerTest.java +++ b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreControllerTest.java @@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -32,6 +33,7 @@ import java.time.OffsetDateTime; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import jakarta.json.Json; @@ -121,10 +123,10 @@ void registerAllowedPolicy() { // act testee.registerAllowedPolicy( - new CreatePolicyRequest(now.plusMinutes(1), jsonObject.get("payload").asJsonObject())); + new CreatePolicyRequest(now.plusMinutes(1), null, List.of(jsonObject.get("payload").asJsonObject()))); // assert - verify(service).registerPolicy(any()); + verify(service).registerPolicy(any(), eq(List.of("default"))); } @Test @@ -132,13 +134,30 @@ void getPolicies() { // arrange final List policies = List.of( new Policy("testId", OffsetDateTime.now(), OffsetDateTime.now(), createPermissions())); - when(service.getStoredPolicies()).thenReturn(policies); + final String bpn = "bpn1"; + when(service.getPolicies(List.of(bpn))).thenReturn(Map.of(bpn, policies)); // act - final List returnedPolicies = testee.getPolicies(); + final Map> returnedPolicies = testee.getPolicies(List.of(bpn)); // assert - assertThat(returnedPolicies).isEqualTo( + assertThat(returnedPolicies.get(bpn)).isEqualTo( + policies.stream().map(PolicyResponse::fromPolicy).collect(Collectors.toList())); + } + + @Test + void getAllPolicies() { + // arrange + final List policies = List.of( + new Policy("testId", OffsetDateTime.now(), OffsetDateTime.now(), createPermissions())); + final String bpn = "bpn1"; + when(service.getPolicies(null)).thenReturn(Map.of(bpn, policies)); + + // act + final Map> returnedPolicies = testee.getPolicies(null); + + // assert + assertThat(returnedPolicies).containsEntry(bpn, policies.stream().map(PolicyResponse::fromPolicy).collect(Collectors.toList())); } @@ -154,14 +173,14 @@ void deleteAllowedPolicy() { @Test void updateAllowedPolicy() { // arrange - final UpdatePolicyRequest request = new UpdatePolicyRequest(OffsetDateTime.now()); + final String policyId = "policyId"; + final UpdatePolicyRequest request = new UpdatePolicyRequest(OffsetDateTime.now(), List.of("bpn"),List.of(policyId)); // act - final String policyId = "policyId"; - testee.updateAllowedPolicy(policyId, request); + testee.updateAllowedPolicy(request); // assert - verify(service).updatePolicy(policyId, request); + verify(service).updatePolicies(request); } private List createPermissions() { diff --git a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/persistence/PolicyPersistenceTest.java b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/persistence/PolicyPersistenceTest.java index 7fe7aedbc1..60a48e3c00 100644 --- a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/persistence/PolicyPersistenceTest.java +++ b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/persistence/PolicyPersistenceTest.java @@ -36,6 +36,7 @@ import java.time.OffsetDateTime; import java.util.List; +import java.util.Map; import java.util.Optional; import com.fasterxml.jackson.core.JsonProcessingException; @@ -73,7 +74,19 @@ void save() throws BlobPersistenceException { final var policy = new Policy("test", OffsetDateTime.now(), OffsetDateTime.now(), emptyList()); // act - testee.save("testBpn", policy); + testee.save(List.of("testBpn"), policy); + + // assert + verify(mockPersistence).putBlob(anyString(), any()); + } + + @Test + void saveWithoutBpn() throws BlobPersistenceException { + // arrange + final var policy = new Policy("test", OffsetDateTime.now(), OffsetDateTime.now(), emptyList()); + + // act + testee.save(List.of("default"), policy); // assert verify(mockPersistence).putBlob(anyString(), any()); @@ -87,7 +100,8 @@ void saveDuplicate() throws BlobPersistenceException, JsonProcessingException { when(mockPersistence.getBlob(anyString())).thenReturn(Optional.of(mapper.writeValueAsBytes(policies))); // act & assert - assertThatThrownBy(() -> testee.save("testBpn", policy)).isInstanceOf(PolicyStoreException.class); + final List bpn = List.of("testBpn"); + assertThatThrownBy(() -> testee.save(bpn, policy)).isInstanceOf(PolicyStoreException.class); } @Test @@ -98,7 +112,8 @@ void saveWithError() throws BlobPersistenceException { new BlobPersistenceException("test", new IllegalStateException())); // act & assert - assertThatThrownBy(() -> testee.save("testBpn", policy)).isInstanceOf(PolicyStoreException.class); + final List bpn = List.of("testBpn"); + assertThatThrownBy(() -> testee.save(bpn, policy)).isInstanceOf(PolicyStoreException.class); } @Test @@ -109,7 +124,8 @@ void saveWithWriteError() throws BlobPersistenceException { .putBlob(any(), any()); // act & assert - assertThatThrownBy(() -> testee.save("testBpn", policy)).isInstanceOf(PolicyStoreException.class); + final List bpn = List.of("testBpn"); + assertThatThrownBy(() -> testee.save(bpn, policy)).isInstanceOf(PolicyStoreException.class); } @Test @@ -127,21 +143,6 @@ void delete() throws BlobPersistenceException, JsonProcessingException { verify(mockPersistence).putBlob(anyString(), any()); } - @Test - void update() throws BlobPersistenceException, JsonProcessingException { - // arrange - final String policyId = "test"; - final var policy = new Policy(policyId, OffsetDateTime.now(), OffsetDateTime.now(), emptyList()); - final var policies = List.of(policy); - when(mockPersistence.getBlob(anyString())).thenReturn(Optional.of(mapper.writeValueAsBytes(policies))); - - // act - testee.update("testBpn", policyId, OffsetDateTime.now()); - - // assert - verify(mockPersistence).putBlob(anyString(), any()); - } - @Test void deleteShouldThrowExceptionIfPolicyWithIdDoesntExists() throws BlobPersistenceException, JsonProcessingException { // arrange @@ -153,25 +154,28 @@ void deleteShouldThrowExceptionIfPolicyWithIdDoesntExists() throws BlobPersisten } @Test - void updateShouldThrowExceptionIfPolicyWithIdDoesntExists() throws BlobPersistenceException, JsonProcessingException { + void readAll() throws BlobPersistenceException, JsonProcessingException { // arrange - final OffsetDateTime now = OffsetDateTime.now(); - final var policy = new Policy("policyId", now, now, emptyList()); - when(mockPersistence.getBlob(anyString())).thenReturn(Optional.of(mapper.writeValueAsBytes(List.of(policy)))); + final var policy = new Policy("test", OffsetDateTime.now(), OffsetDateTime.now(), emptyList()); + final var policies = List.of(policy); + when(mockPersistence.getBlob(anyString())).thenReturn(Optional.of(mapper.writeValueAsBytes(policies))); // act - assertThrows(PolicyStoreException.class, () -> testee.update("testBpn", "notExistingPolicyId", now)); + final var readPolicies = testee.readAll("testBpn"); + + // assert + assertThat(readPolicies).hasSize(1); } @Test - void readAll() throws BlobPersistenceException, JsonProcessingException { + void whenReadAllShouldReturnCorrect() throws BlobPersistenceException, JsonProcessingException { // arrange final var policy = new Policy("test", OffsetDateTime.now(), OffsetDateTime.now(), emptyList()); final var policies = List.of(policy); - when(mockPersistence.getBlob(anyString())).thenReturn(Optional.of(mapper.writeValueAsBytes(policies))); + when(mockPersistence.getAllBlobs()).thenReturn(Map.of("bpn1", mapper.writeValueAsBytes(policies))); // act - final var readPolicies = testee.readAll("testBpn"); + final var readPolicies = testee.readAll(); // assert assertThat(readPolicies).hasSize(1); diff --git a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyHelperTest.java b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyHelperTest.java new file mode 100644 index 0000000000..1362d7a7bb --- /dev/null +++ b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyHelperTest.java @@ -0,0 +1,53 @@ +/******************************************************************************** + * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +package org.eclipse.tractusx.irs.policystore.services; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +import java.util.HashMap; +import java.util.List; + +import org.eclipse.tractusx.irs.edc.client.policy.Policy; +import org.junit.jupiter.api.Test; + +class PolicyHelperTest { + + @Test + void shouldFilterMapByPolicyId() { + + // ARRANGE + final HashMap> policyMap = new HashMap<>(); + final String policyIdToFind = "policyIdToFind"; + policyMap.put("BPN1", List.of(Policy.builder().policyId(policyIdToFind).build(), + Policy.builder().policyId("policy1").build())); + policyMap.put("BPN2", List.of(Policy.builder().policyId("policy2").build(), + Policy.builder().policyId(policyIdToFind).build())); + policyMap.put("BPN3", + List.of(Policy.builder().policyId("policy3").build(), Policy.builder().policyId("policy4").build())); + policyMap.put("BPN4", List.of(Policy.builder().policyId(policyIdToFind).build())); + + // ACT + final List result = PolicyHelper.findBpnsByPolicyId(policyMap, policyIdToFind); + + // ASSERT + assertThat(result).containsExactlyInAnyOrder("BPN1", "BPN2", "BPN4"); + } + +} diff --git a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreServiceTest.java b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreServiceTest.java index e218ca2b94..93a0f38afe 100644 --- a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreServiceTest.java +++ b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyStoreServiceTest.java @@ -24,11 +24,13 @@ package org.eclipse.tractusx.irs.policystore.services; import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -36,6 +38,7 @@ import java.time.OffsetDateTime; import java.util.Collections; import java.util.List; +import java.util.Map; import org.eclipse.tractusx.irs.edc.client.policy.Constraint; import org.eclipse.tractusx.irs.edc.client.policy.Constraints; @@ -74,7 +77,7 @@ class PolicyStoreServiceTest { void setUp() { final DefaultAcceptedPoliciesConfig defaultAcceptedPoliciesConfig = new DefaultAcceptedPoliciesConfig(); defaultAcceptedPoliciesConfig.setAcceptedPolicies(List.of()); - testee = new PolicyStoreService(BPN, defaultAcceptedPoliciesConfig, persistence, clock); + testee = new PolicyStoreService(defaultAcceptedPoliciesConfig, persistence, clock); } @Test @@ -84,10 +87,10 @@ void registerPolicy() { final Policy policy = new Policy("testId", now, now.plusMinutes(1), emptyList()); // act - testee.registerPolicy(policy); + testee.registerPolicy(policy, List.of(BPN)); // assert - verify(persistence).save(eq(BPN), any()); + verify(persistence).save(eq(List.of(BPN)), any()); } @Test @@ -97,10 +100,10 @@ void registerPolicyWithPermission() { final Policy policy = new Policy("testId", now, now.plusMinutes(1), createPermissions()); // act - testee.registerPolicy(policy); + testee.registerPolicy(policy, List.of(BPN)); // assert - verify(persistence).save(eq(BPN), policyCaptor.capture()); + verify(persistence).save(eq(List.of(BPN)), policyCaptor.capture()); assertThat(policyCaptor.getValue()).isNotNull(); List permissionList = policyCaptor.getValue().getPermissions(); @@ -115,10 +118,11 @@ void registerPolicyShouldThrowResponseStatusException() { final String policyId = "testId"; final OffsetDateTime now = OffsetDateTime.now(clock); final Policy policy = new Policy(policyId, now, now.plusMinutes(1), createPermissions()); - doThrow(new PolicyStoreException("")).when(persistence).save(eq(BPN), any()); + doThrow(new PolicyStoreException("")).when(persistence).save(any(), any()); // assert - assertThrows(ResponseStatusException.class, () -> testee.registerPolicy(policy)); + final List bpns = List.of(BPN); + assertThrows(ResponseStatusException.class, () -> testee.registerPolicy(policy, bpns)); } @Test @@ -128,7 +132,7 @@ void getStoredPolicies() { when(persistence.readAll(BPN)).thenReturn(policies); // act - final var storedPolicies = testee.getStoredPolicies(); + final var storedPolicies = testee.getStoredPolicies(List.of(BPN)); // assert assertThat(storedPolicies).hasSize(3); @@ -143,10 +147,10 @@ void getDefaultStoredPoliciesWhenEmpty() { EXAMPLE_ACCEPTED_LEFT_OPERAND, "eq", EXAMPLE_ALLOWED_NAME); final DefaultAcceptedPoliciesConfig defaultAcceptedPoliciesConfig = new DefaultAcceptedPoliciesConfig(); defaultAcceptedPoliciesConfig.setAcceptedPolicies(List.of(acceptedPolicy1, acceptedPolicy2)); - testee = new PolicyStoreService(BPN, defaultAcceptedPoliciesConfig, persistence, clock); + testee = new PolicyStoreService(defaultAcceptedPoliciesConfig, persistence, clock); // act - final var defaultPolicies = testee.getStoredPolicies(); + final var defaultPolicies = testee.getStoredPolicies(List.of(BPN)); // assert assertThat(defaultPolicies).hasSize(1); @@ -175,6 +179,9 @@ private Constraints createConstraints() { @Test void deletePolicy() { + // arrange + when(persistence.readAll()).thenReturn(Map.of(BPN, List.of(new Policy("testId", null, null, null)))); + // act testee.deletePolicy("testId"); @@ -186,6 +193,7 @@ void deletePolicy() { void deletePolicyShouldThrowResponseStatusException() { // act final String policyId = "testId"; + when(persistence.readAll()).thenReturn(Map.of(BPN, List.of(new Policy("testId", null, null, null)))); doThrow(new PolicyStoreException("")).when(persistence).delete(BPN, policyId); // assert @@ -193,50 +201,165 @@ void deletePolicyShouldThrowResponseStatusException() { } @Test - void updatePolicy() { - // act - final String policyId = "testId"; - final OffsetDateTime validUntil = OffsetDateTime.now(); - testee.updatePolicy(policyId, new UpdatePolicyRequest(validUntil)); + void whenRegisterPolicyWithMissingPermissionsShouldThrowException() { + // arrange + final Policy policy = new Policy(); + // act // assert - verify(persistence).update(BPN, policyId, validUntil); + assertThrows(ResponseStatusException.class, () -> testee.registerPolicy(policy, null)); } @Test - void updatePolicyShouldThrowResponseStatusException() { - // act - final String policyId = "testId"; - final OffsetDateTime validUntil = OffsetDateTime.now(); - doThrow(new PolicyStoreException("")).when(persistence).update(BPN, policyId, validUntil); - final UpdatePolicyRequest request = new UpdatePolicyRequest(validUntil); + void whenRegisterPolicyWithMissingConstraintShouldThrowException() { + // arrange + final Policy policy = Policy.builder() + .permissions(List.of(Permission.builder() + .constraint( + new Constraints(emptyList(), emptyList())) + .build(), Permission.builder().build())) + .build(); + // act // assert - assertThrows(ResponseStatusException.class, () -> testee.updatePolicy(policyId, request)); + assertThrows(ResponseStatusException.class, () -> testee.registerPolicy(policy, null)); } @Test - void whenRegisterPolicyWithMissingPermissionsShouldThrowException() { + void whenUpdate() { // arrange - final Policy policy = new Policy(); + final String policyId = "testId"; + + final String originalBpn = "bpn2"; + final String expectedBpn = "bpn1"; + + final OffsetDateTime createdOn = OffsetDateTime.now(clock).minusDays(10); + final OffsetDateTime originalValidUntil = createdOn.plusMinutes(1); + final OffsetDateTime expectedValidUntil = createdOn.plusDays(3); + + final List permissions = emptyList(); + + final Policy testPolicy = new Policy(policyId, createdOn, originalValidUntil, permissions); + when(persistence.readAll()).thenReturn(Map.of(originalBpn, List.of(testPolicy))); + when(persistence.readAll(originalBpn)).thenReturn( + List.of(new Policy(policyId, createdOn, originalValidUntil, permissions))); // act + testee.updatePolicies(new UpdatePolicyRequest(expectedValidUntil, List.of(expectedBpn), List.of(policyId))); + // assert - assertThrows(ResponseStatusException.class, () -> testee.registerPolicy(policy)); + verify(persistence).delete(originalBpn, policyId); + + final var policyCaptor = ArgumentCaptor.forClass(Policy.class); + verify(persistence).save(eq(List.of(expectedBpn)), policyCaptor.capture()); + assertThat(policyCaptor.getValue().getCreatedOn()).isEqualTo(createdOn); + assertThat(policyCaptor.getValue().getValidUntil()).isEqualTo(expectedValidUntil); } + @SuppressWarnings("unchecked") @Test - void whenRegisterPolicyWithMissingConstraintShouldThrowException() { + void updatePolicies_shouldAddPolicyToEachBpn() { + + // ARRANGE + final String policyId = "testId"; + + final OffsetDateTime createdOn = OffsetDateTime.now(clock).minusDays(10); + final OffsetDateTime validUntil = createdOn.plusDays(14); + + final List permissions = emptyList(); + + // BPN1 without any policies + + // BPN2 with testPolicy + final Policy testPolicy = new Policy(policyId, createdOn, validUntil, permissions); + when(persistence.readAll()).thenReturn(Map.of("bpn2", List.of(testPolicy))); + when(persistence.readAll("bpn2")).thenReturn(List.of(testPolicy)); + + // ACT + testee.updatePolicies(new UpdatePolicyRequest(validUntil, List.of("bpn1", "bpn2"), List.of(policyId))); + + // ASSERT + verify(persistence).delete("bpn2", policyId); + + final var bpnsCaptor = ArgumentCaptor.forClass(List.class); + final var policyCaptor = ArgumentCaptor.forClass(Policy.class); + verify(persistence).save(bpnsCaptor.capture(), policyCaptor.capture()); + + // policy added to each BPN + assertThat(policyCaptor.getValue().getPolicyId()).isEqualTo(policyId); + assertThat(bpnsCaptor.getValue()).containsAll(List.of("bpn1", "bpn2")); + } + + @SuppressWarnings("unchecked") + @Test + void updatePolicies_shouldAddBpnsToEachPolicy() { + + // ARRANGE + final String policyId1 = "testId1"; + final String policyId2 = "testId2"; + + final String bpn1 = "bpn1"; + final String bpn2 = "bpn2"; + + final OffsetDateTime createdOn = OffsetDateTime.now(clock).minusDays(10); + final OffsetDateTime originalValidUntil = createdOn.plusMinutes(1); + + final List permissions = emptyList(); + + final Policy testPolicy1 = new Policy(policyId1, createdOn, originalValidUntil, permissions); + final Policy testPolicy2 = new Policy(policyId2, createdOn, originalValidUntil, permissions); + + // BPN1 without any policies + + // BPN2 with testPolicy1 and testPolicy2 + when(persistence.readAll()).thenReturn(Map.of(bpn2, List.of(testPolicy1, testPolicy2))); + when(persistence.readAll(bpn2)).thenReturn( + List.of(new Policy(policyId1, createdOn, originalValidUntil, permissions), + new Policy(policyId2, createdOn, originalValidUntil, permissions))); + + // ACT + testee.updatePolicies( + new UpdatePolicyRequest(originalValidUntil, List.of(bpn1, bpn2), List.of(policyId1, policyId2))); + + // ASSERT + verify(persistence).delete(bpn2, policyId1); + verify(persistence).delete(bpn2, policyId2); + + final var bpnsCaptor = ArgumentCaptor.forClass(List.class); + final var policyCaptor = ArgumentCaptor.forClass(Policy.class); + verify(persistence, times(2)).save(bpnsCaptor.capture(), policyCaptor.capture()); + + // each BPNs added to policy 1 + assertThat(policyCaptor.getAllValues().get(0).getPolicyId()).isEqualTo(policyId1); + assertThat(bpnsCaptor.getAllValues().get(0)).containsAll(List.of("bpn1", "bpn2")); + + // each BPNs added to policy 2 + assertThat(bpnsCaptor.getAllValues().get(1)).containsAll(List.of("bpn1", "bpn2")); + assertThat(policyCaptor.getAllValues().get(1).getPolicyId()).isEqualTo(policyId2); + } + + @Test + void shouldReturnDefaultPolicyWhenBpnIsEmpty() { // arrange - final Policy policy = Policy.builder() - .permissions(List.of( - Permission.builder().constraint(new Constraints(emptyList(), emptyList())).build(), - Permission.builder().build() - )) - .build(); + when(persistence.readAll()).thenReturn(emptyMap()); // act + final var acceptedPolicies = testee.getAcceptedPolicies(null); + // assert - assertThrows(ResponseStatusException.class, () -> testee.registerPolicy(policy)); + assertThat(acceptedPolicies.get(0).policy().getPolicyId()).isEqualTo("default-policy"); } + + @Test + void updatePolicyShouldThrowResponseStatusException() { + // act + final String policyId = "testId"; + final OffsetDateTime validUntil = OffsetDateTime.now(); + doThrow(new PolicyStoreException("")).when(persistence).readAll(); + + // assert + final List bpn = List.of("bpn"); + assertThrows(ResponseStatusException.class, () -> testee.updatePolicy(policyId, validUntil, bpn)); + } + } \ No newline at end of file diff --git a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/DefaultConfiguration.java b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/DefaultConfiguration.java index cb15729950..37a322a9a9 100644 --- a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/DefaultConfiguration.java +++ b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/DefaultConfiguration.java @@ -73,6 +73,7 @@ public class DefaultConfiguration { private static final String CONFIG_VALUE_DECENTRAL = "decentral"; private static final String CONFIG_VALUE_CENTRAL = "central"; private static final int POOL_SIZE = 20; + private static final String DEFAULT = "default"; @Bean @ConditionalOnProperty(prefix = CONFIG_PREFIX, name = CONFIG_FIELD_TYPE, havingValue = CONFIG_VALUE_CENTRAL) @@ -118,9 +119,9 @@ public ConnectorEndpointsService connectorEndpointsService(final DiscoveryFinder @ConditionalOnProperty(prefix = CONFIG_PREFIX, name = CONFIG_FIELD_TYPE, havingValue = CONFIG_VALUE_DECENTRAL) public EndpointDataForConnectorsService endpointDataForConnectorsService(final EdcSubmodelFacade facade) { - final EdcEndpointReferenceRetriever edcEndpointReferenceRetriever = (edcConnectorEndpoint, assetType, assetValue) -> { + final EdcEndpointReferenceRetriever edcEndpointReferenceRetriever = (edcConnectorEndpoint, assetType, assetValue, bpn) -> { try { - return facade.getEndpointReferencesForAsset(edcConnectorEndpoint, assetType, assetValue); + return facade.getEndpointReferencesForAsset(edcConnectorEndpoint, assetType, assetValue, DEFAULT); } catch (EdcClientException e) { throw new EdcRetrieverException(e); } diff --git a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryClient.java b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryClient.java index 1c7a7ed5b3..2ee2e339f9 100644 --- a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryClient.java +++ b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryClient.java @@ -32,7 +32,7 @@ import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; import org.eclipse.tractusx.irs.component.assetadministrationshell.AssetAdministrationShellDescriptor; import org.eclipse.tractusx.irs.component.assetadministrationshell.IdentifierKeyValuePair; -import org.eclipse.tractusx.irs.data.StringMapper; +import org.eclipse.tractusx.irs.registryclient.util.SerializationHelper; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -53,6 +53,8 @@ public class DecentralDigitalTwinRegistryClient { private final String shellDescriptorTemplate; private final String lookupShellsTemplate; + private final SerializationHelper serializationHelper = new SerializationHelper(); + public DecentralDigitalTwinRegistryClient(final RestTemplate edcRestTemplate, @Value("${digitalTwinRegistry.shellDescriptorTemplate:}") final String shellDescriptorTemplate, @Value("${digitalTwinRegistry.lookupShellsTemplate:}") final String lookupShellsTemplate) { @@ -61,10 +63,6 @@ public DecentralDigitalTwinRegistryClient(final RestTemplate edcRestTemplate, this.lookupShellsTemplate = lookupShellsTemplate; } - private static String encodeWithBase64(final String aasIdentifier) { - return Base64.getEncoder().encodeToString(aasIdentifier.getBytes(StandardCharsets.UTF_8)); - } - @Retry(name = "registry") public AssetAdministrationShellDescriptor getAssetAdministrationShellDescriptor( final EndpointDataReference endpointDataReference, final String aasIdentifier) { @@ -78,14 +76,22 @@ public AssetAdministrationShellDescriptor getAssetAdministrationShellDescriptor( @Retry(name = "registry") public LookupShellsResponse getAllAssetAdministrationShellIdsByAssetLink( - final EndpointDataReference endpointDataReference, final List assetIds) { + final EndpointDataReference endpointDataReference, final IdentifierKeyValuePair assetIds) { final String shellLookupEndpoint = endpointDataReference.getEndpoint() + lookupShellsTemplate; final UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(shellLookupEndpoint); - uriBuilder.uriVariables(Map.of(PLACEHOLDER_ASSET_IDS, StringMapper.mapToString(assetIds))); + uriBuilder.uriVariables(Map.of(PLACEHOLDER_ASSET_IDS, encodeWithBase64(assetIds))); return edcRestTemplate.exchange(uriBuilder.build().toUri(), HttpMethod.GET, new HttpEntity<>(null, headers(endpointDataReference)), LookupShellsResponse.class).getBody(); } + private String encodeWithBase64(final String aasIdentifier) { + return Base64.getEncoder().encodeToString(aasIdentifier.getBytes(StandardCharsets.UTF_8)); + } + + private String encodeWithBase64(final IdentifierKeyValuePair assetIds) { + return Base64.getEncoder().encodeToString(serializationHelper.serialize(assetIds)); + } + private HttpHeaders headers(final EndpointDataReference dataReference) { final HttpHeaders headers = new HttpHeaders(); headers.setAccept(List.of(MediaType.APPLICATION_JSON)); diff --git a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryService.java b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryService.java index ab5b05e50c..d7daf1c2f9 100644 --- a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryService.java +++ b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryService.java @@ -159,7 +159,7 @@ private CompletableFuture> fetchShellDescriptors(final Set c log.info("Found {} connector endpoints for bpn '{}'", edcUrls.size(), bpn); calledEndpoints.addAll(edcUrls); - return fetchShellDescriptorsForConnectorEndpoints(keys, edcUrls); + return fetchShellDescriptorsForConnectorEndpoints(keys, edcUrls, bpn); } finally { watch.stop(); @@ -168,10 +168,10 @@ private CompletableFuture> fetchShellDescriptors(final Set c } private CompletableFuture> fetchShellDescriptorsForConnectorEndpoints( - final List keys, final List edcUrls) { + final List keys, final List edcUrls, final String bpn) { final var service = endpointDataForConnectorsService; - final var shellsFuture = service.createFindEndpointDataForConnectorsFutures(edcUrls) + final var shellsFuture = service.createFindEndpointDataForConnectorsFutures(edcUrls, bpn) .stream() .map(edrFuture -> edrFuture.thenCompose(edr -> CompletableFuture.supplyAsync( () -> fetchShellDescriptorsForKey(keys, edr)))) @@ -250,7 +250,7 @@ private String mapToShellId(final EndpointDataReference endpointDataReference, f // Try to map the provided ID to the corresponding asset administration shell ID final var mappingResultStream = decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink( - endpointDataReference, List.of(identifierKeyValuePair)).getResult().stream(); + endpointDataReference, identifierKeyValuePair).getResult().stream(); // Special scenario: Multiple DTs with the same globalAssetId in one DTR, see: // docs/arc42/cross-cutting/discovery-DTR--multiple-DTs-with-the-same-globalAssedId-in-one-DTR.puml @@ -284,7 +284,7 @@ private Collection lookupShellIds(final String bpn) throws RegistryServi log.info("Looking up shell ids for bpn '{}' with connector endpoints {}", bpn, edcUrls); final var endpointDataReferenceFutures = endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures( - edcUrls); + edcUrls, bpn); return lookupShellIds(bpn, endpointDataReferenceFutures); @@ -340,7 +340,7 @@ private Collection lookupShellIds(final String bpn, final EndpointDataRe try { return decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink( endpointDataReference, - List.of(IdentifierKeyValuePair.builder().name("manufacturerId").value(bpn).build())).getResult(); + IdentifierKeyValuePair.builder().name("manufacturerId").value(bpn).build()).getResult(); } finally { watch.stop(); log.info(TOOK_MS, watch.getLastTaskName(), watch.getLastTaskTimeMillis()); diff --git a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/EdcEndpointReferenceRetriever.java b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/EdcEndpointReferenceRetriever.java index d27f5748c7..3b76116a3a 100644 --- a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/EdcEndpointReferenceRetriever.java +++ b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/EdcEndpointReferenceRetriever.java @@ -39,9 +39,11 @@ public interface EdcEndpointReferenceRetriever { * @param edcConnectorEndpoint the endpoint URL * @param assetType the asset type id * @param assetValue the asset type value + * @param bpn bpn value * @return the endpoint data references as list of futures * @throws EdcRetrieverException on any EDC errors */ + @SuppressWarnings("PMD.UseObjectForClearerAPI") List> getEndpointReferencesForAsset(String edcConnectorEndpoint, - String assetType, String assetValue) throws EdcRetrieverException; + String assetType, String assetValue, String bpn) throws EdcRetrieverException; } diff --git a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/EndpointDataForConnectorsService.java b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/EndpointDataForConnectorsService.java index 7b2af22161..c65abe5f1e 100644 --- a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/EndpointDataForConnectorsService.java +++ b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/decentral/EndpointDataForConnectorsService.java @@ -47,7 +47,7 @@ public class EndpointDataForConnectorsService { private final EdcEndpointReferenceRetriever edcSubmodelFacade; public List> createFindEndpointDataForConnectorsFutures( - final List edcUrls) { + final List edcUrls, final String bpn) { final var watch = new StopWatch(); final String msg = "Creating futures to get EndpointDataReferences for endpoints: %s".formatted(edcUrls); @@ -58,7 +58,7 @@ public List> createFindEndpointDataForC try { log.info("Creating futures to get EndpointDataReferences for endpoints: {}", edcUrls); futures = edcUrls.stream() - .flatMap(edcUrl -> createGetEndpointReferencesForAssetFutures(edcUrl).stream()) + .flatMap(edcUrl -> createGetEndpointReferencesForAssetFutures(edcUrl, bpn).stream()) .toList(); return futures; } finally { @@ -69,7 +69,7 @@ public List> createFindEndpointDataForC } private List> createGetEndpointReferencesForAssetFutures( - final String edcUrl) { + final String edcUrl, final String bpn) { final var watch = new StopWatch(); final String msg = "Trying to retrieve EndpointDataReference for connector '%s'".formatted(edcUrl); @@ -78,7 +78,7 @@ private List> createGetEndpointReferenc try { return edcSubmodelFacade.getEndpointReferencesForAsset(edcUrl, DT_REGISTRY_ASSET_TYPE, - DT_REGISTRY_ASSET_VALUE); + DT_REGISTRY_ASSET_VALUE, bpn); } catch (EdcRetrieverException e) { log.warn("Exception occurred when retrieving EndpointDataReference from connector '{}'", edcUrl, e); return List.of(CompletableFuture.failedFuture(e)); diff --git a/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/util/SerializationHelper.java b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/util/SerializationHelper.java new file mode 100644 index 0000000000..ee05e8593b --- /dev/null +++ b/irs-registry-client/src/main/java/org/eclipse/tractusx/irs/registryclient/util/SerializationHelper.java @@ -0,0 +1,52 @@ +/******************************************************************************** + * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +package org.eclipse.tractusx.irs.registryclient.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.SerializationFeature; + +/** + * Serializer helper + */ +public class SerializationHelper { + + private static final ObjectWriter WRITER; + static { + final ObjectMapper mapper = new ObjectMapper(); + mapper.enable(SerializationFeature.INDENT_OUTPUT); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + WRITER = mapper.writer(); + } + + public byte[] serialize(final Object object) { + final ByteArrayOutputStream stream = new ByteArrayOutputStream(); + try { + WRITER.writeValue(stream, object); + return stream.toByteArray(); + } catch (final IOException e) { + return new byte[0]; + } + } +} diff --git a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/DefaultConfigurationTest.java b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/DefaultConfigurationTest.java index 79fff0dda1..e6fdc50904 100644 --- a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/DefaultConfigurationTest.java +++ b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/DefaultConfigurationTest.java @@ -87,13 +87,13 @@ void endpointDataForConnectorsService() throws EdcClientException { final var mock = mock(EdcSubmodelFacade.class); final var endpointAddress = "endpointaddress"; final var endpointDataReference = EndpointDataReference.Builder.newInstance().endpoint(endpointAddress).build(); - when(mock.getEndpointReferencesForAsset(eq(endpointAddress), any(), any())).thenReturn( + when(mock.getEndpointReferencesForAsset(eq(endpointAddress), any(), any(), any())).thenReturn( List.of(CompletableFuture.completedFuture(endpointDataReference))); // ACT final var endpointDataForConnectorsService = testee.endpointDataForConnectorsService(mock); - endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures(List.of(endpointAddress)) // + endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures(List.of(endpointAddress), "bpn") // .forEach(future -> { try { future.get(); @@ -106,17 +106,17 @@ void endpointDataForConnectorsService() throws EdcClientException { }); // ASSERT - verify(mock).getEndpointReferencesForAsset(eq(endpointAddress), any(), any()); + verify(mock).getEndpointReferencesForAsset(eq(endpointAddress), any(), any(), any()); } @Test void endpointDataForConnectorsService_withException() throws EdcClientException { final var mock = mock(EdcSubmodelFacade.class); - when(mock.getEndpointReferencesForAsset(any(), any(), any())).thenThrow(new EdcClientException("test")); + when(mock.getEndpointReferencesForAsset(any(), any(), any(), any())).thenThrow(new EdcClientException("test")); final var endpointDataForConnectorsService = testee.endpointDataForConnectorsService(mock); final var dummyEndpoints = List.of("test"); - endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures(dummyEndpoints).forEach(future -> { + endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures(dummyEndpoints, "bpn").forEach(future -> { assertThatThrownBy(future::get).isInstanceOf(ExecutionException.class) .extracting(Throwable::getCause) .isInstanceOf(EdcRetrieverException.class); diff --git a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryClientTest.java b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryClientTest.java index 823fa5a175..b9599b181f 100644 --- a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryClientTest.java +++ b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryClientTest.java @@ -13,6 +13,7 @@ import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; import org.eclipse.tractusx.irs.component.assetadministrationshell.AssetAdministrationShellDescriptor; +import org.eclipse.tractusx.irs.component.assetadministrationshell.IdentifierKeyValuePair; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.http.HttpMethod; @@ -59,7 +60,7 @@ void shouldCallForAllAssetAdministrationShellIdsByAssetLink() { ResponseEntity.of(Optional.of(LookupShellsResponse.builder().result(Collections.emptyList()).build()))); // when - client.getAllAssetAdministrationShellIdsByAssetLink(endpointDataReference, new ArrayList<>()); + client.getAllAssetAdministrationShellIdsByAssetLink(endpointDataReference, IdentifierKeyValuePair.builder().build()); // then verify(restTemplate).exchange(any(), eq(HttpMethod.GET), any(), eq(LookupShellsResponse.class)); diff --git a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryServiceTest.java b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryServiceTest.java index a2c2dace14..7d2d8cd7c1 100644 --- a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryServiceTest.java +++ b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryServiceTest.java @@ -99,11 +99,11 @@ void shouldReturnExpectedShell() throws RegistryServiceException { when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("address")); final var endpointDataRefFutures = List.of(completedFuture(endpointDataReference)); - when(endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures(anyList())).thenReturn( + when(endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures(anyList(), any())).thenReturn( endpointDataRefFutures); when(decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink(any(), - anyList())).thenReturn(lookupShellsResponse); + any(IdentifierKeyValuePair.class))).thenReturn(lookupShellsResponse); when(decentralDigitalTwinRegistryClient.getAssetAdministrationShellDescriptor(any(), any())).thenReturn( expectedShell); @@ -129,10 +129,10 @@ void whenInterruptedExceptionOccurs() throws ExecutionException, InterruptedExce completedFuture(endpointDataReference("url.to.host1")), // completedFuture(endpointDataReference("url.to.host2"))); when(endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures( - connectorEndpoints)).thenReturn(dataRefFutures); + connectorEndpoints, "bpn")).thenReturn(dataRefFutures); when(decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink(any(), - anyList())).thenReturn(lookupShellsResponse); + any(IdentifierKeyValuePair.class))).thenReturn(lookupShellsResponse); when(decentralDigitalTwinRegistryClient.getAssetAdministrationShellDescriptor(any(), any())).thenReturn( shellDescriptor(emptyList())); @@ -163,10 +163,10 @@ void whenExecutionExceptionOccurs() { final var dataRefFutures = List.of(completedFuture(endpointDataReference("url.to.host"))); when(endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures( - connectorEndpoints)).thenReturn(dataRefFutures); + connectorEndpoints, "bpn")).thenReturn(dataRefFutures); when(decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink(any(), - anyList())).thenReturn(lookupShellsResponse); + any(IdentifierKeyValuePair.class))).thenReturn(lookupShellsResponse); when(decentralDigitalTwinRegistryClient.getAssetAdministrationShellDescriptor(any(), any())).thenReturn( shellDescriptor(emptyList())); @@ -227,10 +227,10 @@ void shouldReturnTheExpectedGlobalAssetId() throws RegistryServiceException { .result(List.of(digitalTwinRegistryKey.shellId())) .build(); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("address")); - when(endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures(anyList())).thenReturn( + when(endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures(anyList(), any())).thenReturn( dataRefFutures); when(decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink(any(), - anyList())).thenReturn(lookupShellsResponse); + any(IdentifierKeyValuePair.class))).thenReturn(lookupShellsResponse); when(decentralDigitalTwinRegistryClient.getAssetAdministrationShellDescriptor(any(), any())).thenReturn( expectedShell); diff --git a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryServiceWiremockTest.java b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryServiceWiremockTest.java index 3086e13764..d4a816441a 100644 --- a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryServiceWiremockTest.java +++ b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/DecentralDigitalTwinRegistryServiceWiremockTest.java @@ -118,7 +118,7 @@ void shouldDiscoverEDCAndRequestRegistry() throws RegistryServiceException, EdcR givenThat(getShellDescriptor200()); final var endpointDataReference = endpointDataReference("assetId"); - when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(any(), any(), any())).thenReturn( + when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(any(), any(), any(), any())).thenReturn( List.of(CompletableFuture.completedFuture(endpointDataReference))); // Act @@ -167,7 +167,7 @@ void shouldThrowInCaseOfLookupShellsError() throws EdcRetrieverException { givenThat(postEdcDiscovery200()); final var endpointDataReference = endpointDataReference("assetId"); - when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(any(), any(), any())).thenReturn( + when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(any(), any(), any(), any())).thenReturn( List.of(CompletableFuture.completedFuture(endpointDataReference))); givenThat(getLookupShells404()); @@ -188,7 +188,7 @@ void shouldThrowInCaseOfShellDescriptorsError() throws EdcRetrieverException { givenThat(postEdcDiscovery200()); final var endpointDataReference = endpointDataReference("assetId"); - when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(any(), any(), any())).thenReturn( + when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(any(), any(), any(), any())).thenReturn( List.of(CompletableFuture.completedFuture(endpointDataReference))); givenThat(getLookupShells200()); @@ -211,7 +211,7 @@ void shouldThrowExceptionOnEmptyShells() throws EdcRetrieverException { givenThat(postEdcDiscovery200()); final var endpointDataReference = endpointDataReference("assetId"); - when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(any(), any(), any())).thenReturn( + when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(any(), any(), any(), any())).thenReturn( List.of(CompletableFuture.completedFuture(endpointDataReference))); givenThat(getLookupShells200Empty()); @@ -241,7 +241,7 @@ void lookupShellIdentifiers_oneEDC_oneDTR() throws RegistryServiceException, Edc // simulate endpoint data reference final var endpointDataReference = endpointDataReference("assetId"); - when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(any(), any(), any())).thenReturn( + when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(any(), any(), any(), any())).thenReturn( List.of(CompletableFuture.completedFuture(endpointDataReference))); // Act @@ -272,9 +272,9 @@ void lookupShellIdentifiers_multipleEDCs_oneDTR(String title, // simulate endpoint data reference final var endpointDataReference = endpointDataReference("assetId"); - when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(eq(edc1Url), any(), any())).thenReturn( + when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(eq(edc1Url), any(), any(), any())).thenReturn( List.of(CompletableFuture.completedFuture(endpointDataReference))); - when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(eq(edc2Url), any(), any())).thenReturn( + when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(eq(edc2Url), any(), any(), any())).thenReturn( endpointDataReferenceForAssetFutures); // Act @@ -317,9 +317,9 @@ void lookupShellIdentifiers_multipleEDCs_multipleDTRs() throws RegistryServiceEx // simulate endpoint data reference final var endpointDataReference1 = endpointDataReference("dtr1-assetId"); final var endpointDataReference2 = endpointDataReference("dtr2-assetId"); - when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(eq(edc1Url), any(), any())).thenReturn( + when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(eq(edc1Url), any(), any(), any())).thenReturn( List.of(CompletableFuture.completedFuture(endpointDataReference1))); - when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(eq(edc2Url), any(), any())).thenReturn( + when(edcEndpointReferenceRetrieverMock.getEndpointReferencesForAsset(eq(edc2Url), any(), any(), any())).thenReturn( List.of(CompletableFuture.completedFuture(endpointDataReference2))); // Act & Assert diff --git a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/EndpointDataForConnectorsServiceTest.java b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/EndpointDataForConnectorsServiceTest.java index b4a8b9f922..3181ef0310 100644 --- a/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/EndpointDataForConnectorsServiceTest.java +++ b/irs-registry-client/src/test/java/org/eclipse/tractusx/irs/registryclient/decentral/EndpointDataForConnectorsServiceTest.java @@ -45,14 +45,15 @@ class EndpointDataForConnectorsServiceTest { private static final String DT_REGISTRY_ASSET_TYPE = "https://w3id.org/edc/v0.0.1/ns/type"; private static final String DT_REGISTRY_ASSET_VALUE = "data.core.digitalTwinRegistry"; - private static final String connectionOneAddress = "connectionOneAddress"; - private static final String connectionTwoAddress = "connectionTwoAddress"; + private static final String CONNECTION_ONE_ADDRESS = "connectionOneAddress"; + private static final String CONNECTION_TWO_ADDRESS = "connectionTwoAddress"; + private static final String BPN = "bpn"; private static final EndpointDataReference CONNECTION_ONE_DATA_REF = // - EndpointDataReference.Builder.newInstance().endpoint(connectionOneAddress).build(); + EndpointDataReference.Builder.newInstance().endpoint(CONNECTION_ONE_ADDRESS).build(); private static final EndpointDataReference CONNECTION_TWO_DATA_REF = // - EndpointDataReference.Builder.newInstance().endpoint(connectionTwoAddress).build(); + EndpointDataReference.Builder.newInstance().endpoint(CONNECTION_TWO_ADDRESS).build(); private final EdcEndpointReferenceRetriever edcSubmodelFacade = mock(EdcEndpointReferenceRetriever.class); @@ -62,20 +63,20 @@ class EndpointDataForConnectorsServiceTest { void shouldReturnExpectedEndpointDataReference() throws EdcRetrieverException { // GIVEN - when(edcSubmodelFacade.getEndpointReferencesForAsset(connectionOneAddress, DT_REGISTRY_ASSET_TYPE, - DT_REGISTRY_ASSET_VALUE)).thenReturn( + when(edcSubmodelFacade.getEndpointReferencesForAsset(CONNECTION_ONE_ADDRESS, DT_REGISTRY_ASSET_TYPE, + DT_REGISTRY_ASSET_VALUE, BPN)).thenReturn( List.of(CompletableFuture.completedFuture(CONNECTION_ONE_DATA_REF))); // WHEN final List> endpointDataReferences = sut.createFindEndpointDataForConnectorsFutures( - Collections.singletonList(connectionOneAddress)); + Collections.singletonList(CONNECTION_ONE_ADDRESS), BPN); // THEN assertThat(endpointDataReferences).isNotEmpty() .extracting(CompletableFuture::get) .isNotEmpty() .extracting(EndpointDataReference::getEndpoint) - .contains(connectionOneAddress); + .contains(CONNECTION_ONE_ADDRESS); } @Test @@ -84,20 +85,20 @@ void shouldReturnExpectedEndpointDataReferenceFromSecondConnectionEndpoint() thr // GIVEN // a first endpoint failing (1) - when(edcSubmodelFacade.getEndpointReferencesForAsset(connectionOneAddress, DT_REGISTRY_ASSET_TYPE, - DT_REGISTRY_ASSET_VALUE)).thenThrow( + when(edcSubmodelFacade.getEndpointReferencesForAsset(CONNECTION_ONE_ADDRESS, DT_REGISTRY_ASSET_TYPE, + DT_REGISTRY_ASSET_VALUE, BPN)).thenThrow( new EdcRetrieverException(new EdcClientException("EdcClientException"))); // and a second endpoint returning successfully (2) - when(edcSubmodelFacade.getEndpointReferencesForAsset(connectionTwoAddress, DT_REGISTRY_ASSET_TYPE, - DT_REGISTRY_ASSET_VALUE)).thenReturn( + when(edcSubmodelFacade.getEndpointReferencesForAsset(CONNECTION_TWO_ADDRESS, DT_REGISTRY_ASSET_TYPE, + DT_REGISTRY_ASSET_VALUE, BPN)).thenReturn( List.of(CompletableFuture.completedFuture(CONNECTION_TWO_DATA_REF))); // WHEN final List> dataRefFutures = // - sut.createFindEndpointDataForConnectorsFutures(List.of(connectionOneAddress, // (1) - connectionTwoAddress // (2) - )); + sut.createFindEndpointDataForConnectorsFutures(List.of(CONNECTION_ONE_ADDRESS, // (1) + CONNECTION_TWO_ADDRESS // (2) + ), BPN); // THEN final List dataReferences = // @@ -108,7 +109,7 @@ void shouldReturnExpectedEndpointDataReferenceFromSecondConnectionEndpoint() thr assertThat(dataReferences).isNotEmpty() // .extracting(EndpointDataReference::getEndpoint) // - .contains(connectionTwoAddress); + .contains(CONNECTION_TWO_ADDRESS); } private static EndpointDataReference executeFutureMappingErrorsToNull( @@ -126,15 +127,15 @@ void shouldThrowExceptionWhenConnectorEndpointsNotReachable() throws EdcRetrieve // GIVEN when(edcSubmodelFacade.getEndpointReferencesForAsset(anyString(), eq(DT_REGISTRY_ASSET_TYPE), - eq(DT_REGISTRY_ASSET_VALUE))).thenThrow( + eq(DT_REGISTRY_ASSET_VALUE), eq(BPN))).thenThrow( new EdcRetrieverException(new EdcClientException("EdcClientException"))); // WHEN final var exceptions = new ArrayList<>(); // THEN - final List connectorEndpoints = List.of(connectionOneAddress, connectionTwoAddress); - sut.createFindEndpointDataForConnectorsFutures(connectorEndpoints) // + final List connectorEndpoints = List.of(CONNECTION_ONE_ADDRESS, CONNECTION_TWO_ADDRESS); + sut.createFindEndpointDataForConnectorsFutures(connectorEndpoints, BPN) // .forEach(future -> { try { future.get(); diff --git a/local/testing/request-collection/IRS_Request_Collection.json b/local/testing/request-collection/IRS_Request_Collection.json index 0722d60f79..0f0b8d6f68 100644 --- a/local/testing/request-collection/IRS_Request_Collection.json +++ b/local/testing/request-collection/IRS_Request_Collection.json @@ -1,15 +1,15 @@ { "_type": "export", "__export_format": 4, - "__export_date": "2024-03-10T13:23:40.100Z", - "__export_source": "insomnia.desktop.app:v2023.5.8", + "__export_date": "2024-03-22T09:31:33.166Z", + "__export_source": "insomnia.desktop.app:v8.6.1", "resources": [ { - "_id": "req_87f0d66bd32b4f2d8551791af7f2e2ed", - "parentId": "fld_6d020c1b8cd44f51b9a2edfff562caf1", - "modified": 1705006817408, + "_id": "req_2d5a4fb5ec0845059533cb9904910156", + "parentId": "fld_c751e5e73d5248a3ae22a44bafae7906", + "modified": 1711099785377, "created": 1705005887617, - "url": "{{IRS_HOST}}/irs/policies", + "url": "{{IRS_HOST}}/irs/policies?bpnls=BPNL00000001CRHK", "name": "Get all policies", "description": "", "method": "GET", @@ -25,6 +25,7 @@ }, "metaSortKey": -1705005887617, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -34,8 +35,8 @@ "_type": "request" }, { - "_id": "fld_6d020c1b8cd44f51b9a2edfff562caf1", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_c751e5e73d5248a3ae22a44bafae7906", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1687243055015, "created": 1687243055015, "name": "Policy Store", @@ -46,8 +47,8 @@ "_type": "request_group" }, { - "_id": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", - "parentId": "wrk_565df8abe30f4da29d8bffcde97927d7", + "_id": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", + "parentId": "wrk_d83bab75184e43adadd63001907af70d", "modified": 1691572726194, "created": 1680682418636, "name": "IRS DEMO Collection", @@ -58,18 +59,18 @@ "_type": "request_group" }, { - "_id": "wrk_565df8abe30f4da29d8bffcde97927d7", + "_id": "wrk_d83bab75184e43adadd63001907af70d", "parentId": null, - "modified": 1680682438221, - "created": 1680682419747, + "modified": 1711099756361, + "created": 1711099756361, "name": "IRS", "description": "", "scope": "collection", "_type": "workspace" }, { - "_id": "req_5696fa47e33c407cbb7a2deac8ddbcd2", - "parentId": "fld_6d020c1b8cd44f51b9a2edfff562caf1", + "_id": "req_ab9376672bd94bd783aa97f36646981b", + "parentId": "fld_c751e5e73d5248a3ae22a44bafae7906", "modified": 1702990529632, "created": 1687243204155, "url": "{{IRS_HOST}}/irs/policies/{% prompt 'policyId', '', 'traceability-test', '', false, true %}", @@ -88,6 +89,7 @@ }, "metaSortKey": -1685602897140.75, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -97,17 +99,17 @@ "_type": "request" }, { - "_id": "req_34b6d543720247a7bcad402cab2d2f7f", - "parentId": "fld_6d020c1b8cd44f51b9a2edfff562caf1", - "modified": 1702990565006, + "_id": "req_a68c5fa596ee4b738eefd6b7b4e2bd7a", + "parentId": "fld_c751e5e73d5248a3ae22a44bafae7906", + "modified": 1711099840007, "created": 1693576003390, - "url": "{{IRS_HOST}}/irs/policies/{% prompt 'id', '', 'traceability-test', '', false, true %}", + "url": "{{IRS_HOST}}/irs/policies", "name": "Update policy", "description": "", "method": "PUT", "body": { "mimeType": "application/json", - "text": "{\n \"validUntil\": \"2025-12-12T23:59:59.999Z\"\n}" + "text": "{\n \"validUntil\": \"2025-12-12T23:59:59.999Z\",\n\t\"businessPartnerNumbers\": [\n\t\t\"BPNL00000001CRHK\"\n\t],\n\t\"policiesIds\": [\n\t\t\"policyId\"\n\t]\n}" }, "parameters": [], "headers": [ @@ -125,6 +127,7 @@ }, "metaSortKey": -1684874704117.875, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -134,9 +137,9 @@ "_type": "request" }, { - "_id": "req_82102b5d71704eae97e5b50dad29a262", - "parentId": "fld_6d020c1b8cd44f51b9a2edfff562caf1", - "modified": 1707126688041, + "_id": "req_95aa08cefddc4743afc85fcabf40e4ee", + "parentId": "fld_c751e5e73d5248a3ae22a44bafae7906", + "modified": 1711099862861, "created": 1687243182397, "url": "{{IRS_HOST}}/irs/policies", "name": "Register policy", @@ -144,7 +147,7 @@ "method": "POST", "body": { "mimeType": "application/json", - "text": "{\n\t\"validUntil\": \"2025-12-12T23:59:59.999Z\",\n\t\"payload\": {\n\t\t\"@context\": {\n\t\t\t\"odrl\": \"http://www.w3.org/ns/odrl/2/\"\n\t\t},\n\t\t\"@id\": \"policy-id12\",\n\t\t\"policy\": {\n\t\t\t\"odrl:permission\": [\n\t\t\t\t{\n\t\t\t\t\t\"odrl:action\": \"USE\",\n\t\t\t\t\t\"odrl:constraint\": {\n\t\t\t\t\t\t\"odrl:and\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"odrl:leftOperand\": \"Membership\",\n\t\t\t\t\t\t\t\t\"odrl:operator\": {\n\t\t\t\t\t\t\t\t\t\"@id\": \"odrl:eq\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"odrl:rightOperand\": \"active\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"odrl:leftOperand\": \"PURPOSE\",\n\t\t\t\t\t\t\t\t\"odrl:operator\": {\n\t\t\t\t\t\t\t\t\t\"@id\": \"odrl:eq\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\"odrl:rightOperand\": \"ID 3.1 Trace\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t}\n}" + "text": "{\n\t\"validUntil\": \"2025-12-12T23:59:59.999Z\",\n\t\"businessPartnerNumbers\": [\n\t\t\"BPNL00000001CRHK\"\n\t],\n\t\"payload\": [\n\t\t{\n\t\t\t\"@context\": {\n\t\t\t\t\"odrl\": \"http://www.w3.org/ns/odrl/2/\"\n\t\t\t},\n\t\t\t\"@id\": \"test-1\",\n\t\t\t\"policy\": {\n\t\t\t\t\"odrl:permission\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"odrl:action\": \"USE\",\n\t\t\t\t\t\t\"odrl:constraint\": {\n\t\t\t\t\t\t\t\"odrl:and\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"odrl:leftOperand\": \"Membership\",\n\t\t\t\t\t\t\t\t\t\"odrl:operator\": {\n\t\t\t\t\t\t\t\t\t\t\"@id\": \"odrl:eq\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"odrl:rightOperand\": \"active\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"odrl:leftOperand\": \"PURPOSE\",\n\t\t\t\t\t\t\t\t\t\"odrl:operator\": {\n\t\t\t\t\t\t\t\t\t\t\"@id\": \"odrl:eq\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"odrl:rightOperand\": \"ID 3.1 Trace\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"@context\": {\n\t\t\t\t\"odrl\": \"http://www.w3.org/ns/odrl/2/\"\n\t\t\t},\n\t\t\t\"@id\": \"test-12\",\n\t\t\t\"policy\": {\n\t\t\t\t\"odrl:permission\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"odrl:action\": \"USE\",\n\t\t\t\t\t\t\"odrl:constraint\": {\n\t\t\t\t\t\t\t\"odrl:and\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"odrl:leftOperand\": \"Membership\",\n\t\t\t\t\t\t\t\t\t\"odrl:operator\": {\n\t\t\t\t\t\t\t\t\t\t\"@id\": \"odrl:eq\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"odrl:rightOperand\": \"active\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"odrl:leftOperand\": \"PURPOSE\",\n\t\t\t\t\t\t\t\t\t\"odrl:operator\": {\n\t\t\t\t\t\t\t\t\t\t\"@id\": \"odrl:eq\"\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\"odrl:rightOperand\": \"ID 3.1 Trace\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t]\n}" }, "parameters": [], "headers": [ @@ -162,6 +165,7 @@ }, "metaSortKey": -1683962737633.5, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -171,8 +175,8 @@ "_type": "request" }, { - "_id": "req_01d928eddda6422eae8f9e6722997640", - "parentId": "fld_bd90851d07ce4f4bad16dc5665dcf3c1", + "_id": "req_b22ea4121d2249e0830489b188ec21e4", + "parentId": "fld_5930ffca903d46feb1793ebd290dde47", "modified": 1706003275081, "created": 1680682418619, "url": "{{DIGITAL_TWIN_REGISTRY}}/api/v3.0/shell-descriptors/{% prompt 'aasIdentifier', '', _.GLOBAL_ASSET_ID, '', false, true %}", @@ -193,6 +197,7 @@ "authentication": {}, "metaSortKey": -1680682418619, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -202,8 +207,8 @@ "_type": "request" }, { - "_id": "fld_bd90851d07ce4f4bad16dc5665dcf3c1", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_5930ffca903d46feb1793ebd290dde47", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1691504187689, "created": 1680682418630, "name": "Digital Twin Registry", @@ -214,8 +219,8 @@ "_type": "request_group" }, { - "_id": "req_c6d045b660f949499151f63e60f51225", - "parentId": "fld_bd90851d07ce4f4bad16dc5665dcf3c1", + "_id": "req_ca1125488c45483c9ddda17955067893", + "parentId": "fld_5930ffca903d46feb1793ebd290dde47", "modified": 1706002920212, "created": 1690529035794, "url": "{{DIGITAL_TWIN_REGISTRY}}/api/v3.0/shell-descriptors", @@ -236,6 +241,7 @@ "authentication": {}, "metaSortKey": -1680682418614, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -245,8 +251,8 @@ "_type": "request" }, { - "_id": "req_c183c331cf2c418e8e89ce95dee5ddbd", - "parentId": "fld_bd90851d07ce4f4bad16dc5665dcf3c1", + "_id": "req_6735560470e644d2b0378e7bddf1b99e", + "parentId": "fld_5930ffca903d46feb1793ebd290dde47", "modified": 1706003278149, "created": 1680682418609, "url": "{{DIGITAL_TWIN_REGISTRY}}/api/v3.0/lookup/shells", @@ -315,6 +321,7 @@ "authentication": {}, "metaSortKey": -1680682418609, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -324,8 +331,8 @@ "_type": "request" }, { - "_id": "req_24a9b4f03e7a498dbc51aecea0ca3492", - "parentId": "fld_bd90851d07ce4f4bad16dc5665dcf3c1", + "_id": "req_837d51ff21e140ab96da276abdaaef54", + "parentId": "fld_5930ffca903d46feb1793ebd290dde47", "modified": 1706003280850, "created": 1680682418595, "url": "{{DIGITAL_TWIN_REGISTRY}}/api/v3.0/lookup/shells", @@ -352,6 +359,7 @@ "authentication": {}, "metaSortKey": -1680682418595, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -361,8 +369,8 @@ "_type": "request" }, { - "_id": "req_5fb54d629b714382ae77c4918a848844", - "parentId": "fld_bd90851d07ce4f4bad16dc5665dcf3c1", + "_id": "req_9332ba908a3648328059a85fc5583ac9", + "parentId": "fld_5930ffca903d46feb1793ebd290dde47", "modified": 1706003354109, "created": 1680682418581, "url": "{{DIGITAL_TWIN_REGISTRY}}/api/v3.0/lookup/shells", @@ -389,6 +397,7 @@ "authentication": {}, "metaSortKey": -1680682418581, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -398,8 +407,8 @@ "_type": "request" }, { - "_id": "req_0231f2221b0b4c52b6f8f82654b40b97", - "parentId": "fld_bd90851d07ce4f4bad16dc5665dcf3c1", + "_id": "req_0b28f257a75249d084c0cedad0e3c655", + "parentId": "fld_5930ffca903d46feb1793ebd290dde47", "modified": 1706003284715, "created": 1680682418570, "url": "{{DIGITAL_TWIN_REGISTRY}}/api/v3.0/lookup/shells/query", @@ -427,6 +436,7 @@ "authentication": {}, "metaSortKey": -1680682418570, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -436,8 +446,8 @@ "_type": "request" }, { - "_id": "req_0e9e498304f1450db30ccd7633c1d044", - "parentId": "fld_bd90851d07ce4f4bad16dc5665dcf3c1", + "_id": "req_f593512f0af543a6b70242da819df2db", + "parentId": "fld_5930ffca903d46feb1793ebd290dde47", "modified": 1706003286642, "created": 1691408320970, "url": "{{DIGITAL_TWIN_REGISTRY}}/api/v3.0/lookup/shells/query", @@ -465,6 +475,7 @@ "authentication": {}, "metaSortKey": -1680682418560.5, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -474,8 +485,8 @@ "_type": "request" }, { - "_id": "req_c45556a411394ae7acaf7b0d7a52c64c", - "parentId": "fld_bd90851d07ce4f4bad16dc5665dcf3c1", + "_id": "req_bbb801fd3b2b444bb3318a8de92918a9", + "parentId": "fld_5930ffca903d46feb1793ebd290dde47", "modified": 1706003289343, "created": 1689167429413, "url": "{{DIGITAL_TWIN_REGISTRY}}/api/v3.0/shell-descriptors/{% prompt 'id', '', '', '', false, true %}", @@ -504,6 +515,7 @@ "authentication": {}, "metaSortKey": -1680682418470, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -513,8 +525,8 @@ "_type": "request" }, { - "_id": "req_4598fa44ca1e445f84dcc88b69e68b2d", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_7ea6d52eea2442ba82a8255041f3cb39", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991054859, "created": 1680682418551, "url": "{{IRS_HOST}}/irs/jobs", @@ -541,6 +553,7 @@ }, "metaSortKey": -1680682418551, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -550,8 +563,8 @@ "_type": "request" }, { - "_id": "fld_99916d6788d445df86cffea2202c7faf", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_80d0dfda7d9849f8923030bcb64169a7", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1680682418562, "created": 1680682418562, "name": "IRS Test Collection", @@ -562,8 +575,8 @@ "_type": "request_group" }, { - "_id": "req_1789ac98712b4774a9478e25eb589bf0", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_b5a068e9bd7044c699f03ee26a1c7499", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991058493, "created": 1680682418539, "url": "{{IRS_HOST}}/irs/jobs", @@ -590,6 +603,7 @@ }, "metaSortKey": -1680682418539, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -599,8 +613,8 @@ "_type": "request" }, { - "_id": "req_3a2d07190c9546378a10b66b6ff4f462", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_f32ea4db7e4e4c0fa9a4058f20ab3a58", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991063641, "created": 1680682418524, "url": "{{IRS_HOST}}/irs/jobs", @@ -627,6 +641,7 @@ }, "metaSortKey": -1680682418524, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -636,8 +651,8 @@ "_type": "request" }, { - "_id": "req_8a3d036a282e403481b73587111f6aa7", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_fa7ee06927f942a88dcf9d047a59dd22", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991067797, "created": 1680682418514, "url": "{{IRS_HOST}}/irs/jobs", @@ -664,6 +679,7 @@ }, "metaSortKey": -1680682418514, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -673,8 +689,8 @@ "_type": "request" }, { - "_id": "req_3dfcf0469334429f8ed26e7cb3b1e7b4", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_0a75e90c3b8c4f4cb2088d456b0d1d98", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991071709, "created": 1680682418504, "url": "{{IRS_HOST}}/irs/jobs", @@ -701,6 +717,7 @@ }, "metaSortKey": -1680682418504, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -710,8 +727,8 @@ "_type": "request" }, { - "_id": "req_8bf909bae9f54371a9056e6c4b9eefca", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_4424152376ce49e1b00d404b4346b9e4", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991076696, "created": 1695042901876, "url": "{{IRS_HOST}}/irs/jobs", @@ -738,6 +755,7 @@ }, "metaSortKey": -1680682418496, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -747,8 +765,8 @@ "_type": "request" }, { - "_id": "req_dc785af1908140b4b28e72a7b89c10e2", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_b8bcd1059fa0428fa74db6e0df9a549c", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076144872, "created": 1680682418488, "url": "{{IRS_HOST}}/irs/jobs", @@ -775,6 +793,7 @@ }, "metaSortKey": -1680682418488, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -784,8 +803,8 @@ "_type": "request" }, { - "_id": "req_1d2d60468a46479aa620856c3af9edad", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_1f8b0bee14394eebbd17f2a845491f5b", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076455844, "created": 1680682418479, "url": "{{IRS_HOST}}/irs/jobs", @@ -812,6 +831,7 @@ }, "metaSortKey": -1680682418479, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -821,8 +841,8 @@ "_type": "request" }, { - "_id": "req_e4781ee7f21c4269877a90c7b3763747", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_3d4c81094d24462c9f6eb69069dabfcf", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076515556, "created": 1680682418469, "url": "{{IRS_HOST}}/irs/jobs", @@ -849,6 +869,7 @@ }, "metaSortKey": -1680682418469, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -858,8 +879,8 @@ "_type": "request" }, { - "_id": "req_4454faa5384d4e1a9eed077d9bb439d3", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_d11875dae2e142cd99de8db2594b5749", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076741632, "created": 1680682418442, "url": "{{IRS_HOST}}/irs/jobs", @@ -886,6 +907,7 @@ }, "metaSortKey": -1680682418442, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -895,8 +917,8 @@ "_type": "request" }, { - "_id": "req_14d8a81103934ca8bde6a913419b6965", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_3664de01c8554ff89c651dff9e0821ab", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076751758, "created": 1680682418432, "url": "{{IRS_HOST}}/irs/jobs", @@ -923,6 +945,7 @@ }, "metaSortKey": -1680682418432, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -932,8 +955,8 @@ "_type": "request" }, { - "_id": "req_4d162553ba09443686bb9e8e90e01f97", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_60839c35d2124c9fbb593969fcc552df", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076760570, "created": 1695192937155, "url": "{{IRS_HOST}}/irs/jobs", @@ -960,6 +983,7 @@ }, "metaSortKey": -1680682418428, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -969,8 +993,8 @@ "_type": "request" }, { - "_id": "req_2bdd38ac17234d7286dc03f0c2741d25", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_5215512817494d63918383988c06144c", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076769119, "created": 1695192971825, "url": "{{IRS_HOST}}/irs/jobs", @@ -997,6 +1021,7 @@ }, "metaSortKey": -1680682418426, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1006,8 +1031,8 @@ "_type": "request" }, { - "_id": "req_56ce00c13b6e42329fb3ed6d18a134eb", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_050aba71af544728bf13966232a68c94", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076214310, "created": 1680682418424, "url": "{{IRS_HOST}}/irs/jobs", @@ -1034,6 +1059,7 @@ }, "metaSortKey": -1680682418424, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1043,8 +1069,8 @@ "_type": "request" }, { - "_id": "req_c4e086d67cb64786b235745f4e56f24c", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_245ceb95afa8407ba017e6143e942557", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991130711, "created": 1680682418414, "url": "{{IRS_HOST}}/irs/jobs", @@ -1071,6 +1097,7 @@ }, "metaSortKey": -1680682418414, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1080,8 +1107,8 @@ "_type": "request" }, { - "_id": "req_2571426d88934df39d76364ce94533a9", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_5c0c50a042914805a4f00cc38e6ec327", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076937249, "created": 1680682418401, "url": "{{IRS_HOST}}/irs/jobs", @@ -1108,6 +1135,7 @@ }, "metaSortKey": -1680682418401, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1117,8 +1145,8 @@ "_type": "request" }, { - "_id": "req_f0b3da6d108f475cb429c99bd9c57dc5", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_fd882f9ee36c4efaaaaad5ee15110e95", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076677384, "created": 1680682418392, "url": "{{IRS_HOST}}/irs/jobs", @@ -1145,6 +1173,7 @@ }, "metaSortKey": -1680682418392, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1154,8 +1183,8 @@ "_type": "request" }, { - "_id": "req_f8f3e3d937e341e388abd88454f31cc2", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_7c176ef2953f4ef3a9bafdf1fdc4f59c", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076237949, "created": 1683184048412, "url": "{{IRS_HOST}}/irs/jobs", @@ -1182,6 +1211,7 @@ }, "metaSortKey": -1680682418386.5, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1191,8 +1221,8 @@ "_type": "request" }, { - "_id": "req_6d86d4ad672a454f85f03672926d6f3c", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_e72bfa320e9d44c7b5df861133034f65", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076397373, "created": 1693493383337, "url": "{{IRS_HOST}}/irs/jobs", @@ -1219,6 +1249,7 @@ }, "metaSortKey": -1680682418382.375, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1228,8 +1259,8 @@ "_type": "request" }, { - "_id": "req_9f6f900788a94461a3856dff0fd3102b", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_d0b0ebd7ab684c038163cbda0d8e38b2", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076245754, "created": 1693493584873, "url": "{{IRS_HOST}}/irs/jobs", @@ -1256,6 +1287,7 @@ }, "metaSortKey": -1680682418381.6875, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1265,8 +1297,8 @@ "_type": "request" }, { - "_id": "req_b4dabeb86fed4de5b54c32a250f94196", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_daed8469e6804426b06e685c13c5a2ee", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076391502, "created": 1693493594373, "url": "{{IRS_HOST}}/irs/jobs", @@ -1293,6 +1325,7 @@ }, "metaSortKey": -1680682418381.3438, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1302,8 +1335,8 @@ "_type": "request" }, { - "_id": "req_35ef2aef21804c3cb86a9aabc7eba0ab", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_3ee66542ae4d4bd086097cc127901a0d", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1710076385497, "created": 1693493604521, "url": "{{IRS_HOST}}/irs/jobs", @@ -1330,6 +1363,7 @@ }, "metaSortKey": -1680682418381.1719, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1339,8 +1373,8 @@ "_type": "request" }, { - "_id": "req_d27e4316d77c4a48adbe27e65390cda8", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_db0100a82fdc4bd7ac88f5fcbfc951f7", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991173689, "created": 1680682418381, "url": "{{IRS_HOST}}/irs/jobs", @@ -1350,7 +1384,7 @@ "body": {}, "parameters": [ { - "name": "jobStates", + "name": "states", "value": "COMPLETED", "disabled": false } @@ -1370,6 +1404,7 @@ }, "metaSortKey": -1680682418381, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1379,8 +1414,8 @@ "_type": "request" }, { - "_id": "req_d8fdde14cf9144ff805a51ff292b9382", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_bf1ded5777714303b33ecc6d802d65ac", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991177973, "created": 1680682418372, "url": "{{IRS_HOST}}/irs/jobs", @@ -1390,7 +1425,7 @@ "body": {}, "parameters": [ { - "name": "jobStates", + "name": "states", "value": "ERROR", "disabled": false } @@ -1410,6 +1445,7 @@ }, "metaSortKey": -1680682418372, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1419,8 +1455,8 @@ "_type": "request" }, { - "_id": "req_19d3cc30b4644dd8957cf980f3ee10ff", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_6dbc72ee2c494a1784766b54862ed682", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991182139, "created": 1680682418358, "url": "{{IRS_HOST}}/irs/jobs", @@ -1430,7 +1466,7 @@ "body": {}, "parameters": [ { - "name": "jobStates", + "name": "states", "value": "INITIAL", "disabled": false } @@ -1450,6 +1486,7 @@ }, "metaSortKey": -1680682418358, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1459,8 +1496,8 @@ "_type": "request" }, { - "_id": "req_7801aee13dd5435a8db10338a2d4f95b", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_ac1c2b21900440d4901111176675e2ff", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991186114, "created": 1680682418348, "url": "{{IRS_HOST}}/irs/jobs", @@ -1484,6 +1521,7 @@ }, "metaSortKey": -1680682418348, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1493,8 +1531,8 @@ "_type": "request" }, { - "_id": "req_1687b685ea5949c89c8c61e483dc60f0", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_53fd3aefa06945f8aea85d3b3c322699", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991190326, "created": 1680682418339, "url": "{{IRS_HOST}}/irs/jobs", @@ -1504,7 +1542,7 @@ "body": {}, "parameters": [ { - "name": "jobStates", + "name": "states", "value": "RUNNING", "disabled": false } @@ -1524,6 +1562,7 @@ }, "metaSortKey": -1680682418339, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1533,8 +1572,8 @@ "_type": "request" }, { - "_id": "req_d4d21a45adbc4398a37eb64325f96277", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_0f0101575ead4084b46710bfb0091f3f", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991196283, "created": 1680682418325, "url": "{{IRS_HOST}}/irs/jobs/{% prompt 'Job ID', '', '', '', false, true %}", @@ -1564,6 +1603,7 @@ }, "metaSortKey": -1680682418325, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1573,8 +1613,8 @@ "_type": "request" }, { - "_id": "req_9baf580bb6384fcea6cd181bc4019c97", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_c50ba332341e4018b4313e7e72695954", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991200399, "created": 1680682418316, "url": "{{IRS_HOST}}/irs/jobs/{% prompt 'Job ID', '', '', '', false, true %}", @@ -1598,6 +1638,7 @@ }, "metaSortKey": -1680682418316, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1607,8 +1648,8 @@ "_type": "request" }, { - "_id": "req_ea9dc2c81dae4b4e945c52ed81a233b9", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_bfcb98fc286a4be79030c9513ed9735f", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991205447, "created": 1680682418307, "url": "{{IRS_HOST}}/irs/jobs/test", @@ -1632,6 +1673,7 @@ }, "metaSortKey": -1680682418307, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1641,8 +1683,8 @@ "_type": "request" }, { - "_id": "req_0808b16bfb534c7e859834972a64ffd0", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_35c58b65dd9d4582ab9472ad1c9d3e3b", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991214202, "created": 1680682418297, "url": "{{IRS_HOST}}/irs/jobs/00000000-0000-0000-0000-000000000000", @@ -1666,6 +1708,7 @@ }, "metaSortKey": -1680682418297, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1675,8 +1718,8 @@ "_type": "request" }, { - "_id": "req_c28839aad9394b2bbda87017500ed616", - "parentId": "fld_99916d6788d445df86cffea2202c7faf", + "_id": "req_896fa0136d6e49d69a938f4de5811bad", + "parentId": "fld_80d0dfda7d9849f8923030bcb64169a7", "modified": 1702991218362, "created": 1680682418280, "url": "{{IRS_HOST}}/irs/jobs/{% prompt 'Job ID', '', '', '', false, true %}", @@ -1700,6 +1743,7 @@ }, "metaSortKey": -1680682418280, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1709,8 +1753,8 @@ "_type": "request" }, { - "_id": "req_d8919afd30d44d1a846084157de8c69d", - "parentId": "fld_9bf5f1410d1b4472b588bfe79bae6d2d", + "_id": "req_69f863ad2c674907ad29581828ba5c43", + "parentId": "fld_7a3a1e3a4fe8428098021e110a52ba0d", "modified": 1705942015684, "created": 1682672699249, "url": "{{ _.BPN_DISCOVERY }}/api/administration/connectors/bpnDiscovery/search", @@ -1738,6 +1782,7 @@ }, "metaSortKey": -1683630902023, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1747,8 +1792,8 @@ "_type": "request" }, { - "_id": "fld_9bf5f1410d1b4472b588bfe79bae6d2d", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_7a3a1e3a4fe8428098021e110a52ba0d", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1683630931664, "created": 1683630887514, "name": "Discovery", @@ -1759,8 +1804,8 @@ "_type": "request_group" }, { - "_id": "req_01422217227b452a98e7db4cb60ca5bd", - "parentId": "fld_9bf5f1410d1b4472b588bfe79bae6d2d", + "_id": "req_7ba23e27b73845c9a9b566c72f4f0c29", + "parentId": "fld_7a3a1e3a4fe8428098021e110a52ba0d", "modified": 1705942027574, "created": 1683031718699, "url": "{{ _.DISCOVERY_FINDER }}/api/administration/connectors/discovery/search", @@ -1788,6 +1833,7 @@ }, "metaSortKey": -1683630901923, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1797,8 +1843,8 @@ "_type": "request" }, { - "_id": "req_1357c99d62684a7b93cde637b6490d11", - "parentId": "fld_9bf5f1410d1b4472b588bfe79bae6d2d", + "_id": "req_4325898bf3df40648ad9cf8b304a58ee", + "parentId": "fld_7a3a1e3a4fe8428098021e110a52ba0d", "modified": 1705942036978, "created": 1683560906453, "url": "{{ _.EDC_DISCOVERY }}/api/administration/connectors/discovery", @@ -1826,6 +1872,7 @@ }, "metaSortKey": -1683630901873, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1835,8 +1882,8 @@ "_type": "request" }, { - "_id": "req_3261038fea10412c9f1daf62c3129529", - "parentId": "fld_b5db89748d844f92a8e2f577faa58f25", + "_id": "req_349d613f763d4102bee054dcfd5da1bc", + "parentId": "fld_1ef343e864c14d44b2f8aa660aa7e5ac", "modified": 1710076352238, "created": 1680682418265, "url": "{{IRS_HOST}}/irs/jobs", @@ -1863,6 +1910,7 @@ }, "metaSortKey": -1680682418265, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1872,8 +1920,8 @@ "_type": "request" }, { - "_id": "fld_b5db89748d844f92a8e2f577faa58f25", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_1ef343e864c14d44b2f8aa660aa7e5ac", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1680682418273, "created": 1680682418273, "name": "IRS Basic API Calls", @@ -1884,8 +1932,8 @@ "_type": "request_group" }, { - "_id": "req_b5192703cc404e838b2e9f127674b6a9", - "parentId": "fld_b5db89748d844f92a8e2f577faa58f25", + "_id": "req_9b5111fd12ea47639c6621d23ddc528c", + "parentId": "fld_1ef343e864c14d44b2f8aa660aa7e5ac", "modified": 1705942154792, "created": 1680682418238, "url": "{{IRS_HOST}}/irs/jobs/{% response 'body', 'req_b02ac0bfc4704c83a5c5f8b24175d61a', 'b64::JC5pZA==::46b', 'never', 60 %} ", @@ -1915,6 +1963,7 @@ }, "metaSortKey": -1680682418261, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1924,8 +1973,8 @@ "_type": "request" }, { - "_id": "req_5a857366bb044122b7bebd64aa58c4f9", - "parentId": "fld_b5db89748d844f92a8e2f577faa58f25", + "_id": "req_0a7c66ccddb04f9caca830e197aecf64", + "parentId": "fld_1ef343e864c14d44b2f8aa660aa7e5ac", "modified": 1702991288793, "created": 1680682418257, "url": "{{IRS_HOST}}/irs/jobs", @@ -1949,6 +1998,7 @@ }, "metaSortKey": -1680682418257, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -1958,8 +2008,8 @@ "_type": "request" }, { - "_id": "req_08470d1692b24a5eb0be4f34cdac0088", - "parentId": "fld_b5db89748d844f92a8e2f577faa58f25", + "_id": "req_3d05fdc2d1e24d60960031834adf6753", + "parentId": "fld_1ef343e864c14d44b2f8aa660aa7e5ac", "modified": 1702991284435, "created": 1680682418247, "url": "{{IRS_HOST}}/irs/jobs", @@ -1969,20 +2019,20 @@ "body": {}, "parameters": [ { - "name": "jobStates", + "name": "states", "value": "ERROR", "disabled": true, "id": "pair_c694b66f41e649db837f801b5699859e" }, { - "name": "jobStates", + "name": "states", "value": "CANCELED,COMPLETED", "disabled": false, "id": "pair_ab346623e5394504b7232cc40ae75bed" }, { "id": "pair_ddbccd5219944e8cac3d99249ba881e5", - "name": "jobStates", + "name": "states", "value": "RUNNING", "description": "", "disabled": true @@ -2003,6 +2053,7 @@ }, "metaSortKey": -1680682418247, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2012,8 +2063,8 @@ "_type": "request" }, { - "_id": "req_3dc3438d10ec4540ac5273a3e5a9b83e", - "parentId": "fld_b5db89748d844f92a8e2f577faa58f25", + "_id": "req_22194c017aac4261bb344662839de6f5", + "parentId": "fld_1ef343e864c14d44b2f8aa660aa7e5ac", "modified": 1703236659047, "created": 1690384427379, "url": "{{IRS_HOST}}/irs/jobs/{% prompt 'Job ID', '', '', '', false, true %}", @@ -2043,6 +2094,7 @@ }, "metaSortKey": -1680682418238, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2052,8 +2104,8 @@ "_type": "request" }, { - "_id": "req_992a742bd2274479bddc627789274c45", - "parentId": "fld_b5db89748d844f92a8e2f577faa58f25", + "_id": "req_95ccc8f10f584a4aaf4d2a0b9c44441b", + "parentId": "fld_1ef343e864c14d44b2f8aa660aa7e5ac", "modified": 1702991276045, "created": 1680682418229, "url": "{{IRS_HOST}}/irs/jobs/{% prompt 'Job ID', '', '', '', false, true %}", @@ -2077,6 +2129,7 @@ }, "metaSortKey": -1680682418229, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2086,8 +2139,8 @@ "_type": "request" }, { - "_id": "req_e3487fdf1f844cc58ff1d5f13cefe638", - "parentId": "fld_b5db89748d844f92a8e2f577faa58f25", + "_id": "req_d677e6e5a736406ba05aea1a9a98595a", + "parentId": "fld_1ef343e864c14d44b2f8aa660aa7e5ac", "modified": 1702991272198, "created": 1682498338739, "url": "{{IRS_HOST}}/irs/aspectmodels", @@ -2111,6 +2164,7 @@ }, "metaSortKey": -1680682418179, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2120,8 +2174,8 @@ "_type": "request" }, { - "_id": "req_98b454b45f5c4cad933df80c0ca8ff5c", - "parentId": "fld_9dceb37ce1154d0095a71bdb36fe4a79", + "_id": "req_b1a92060c1bd47078fbee001952da6d8", + "parentId": "fld_187756e90d514741a65cb9617a3ea41a", "modified": 1705942066941, "created": 1680682418213, "url": "{{ _.SEMANTIC_HUB_URL }}/hub/api/v1/models", @@ -2153,6 +2207,7 @@ }, "metaSortKey": -1680682418213, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2162,8 +2217,8 @@ "_type": "request" }, { - "_id": "fld_9dceb37ce1154d0095a71bdb36fe4a79", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_187756e90d514741a65cb9617a3ea41a", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1680682418222, "created": 1680682418222, "name": "Semantics Hub", @@ -2174,8 +2229,8 @@ "_type": "request_group" }, { - "_id": "req_7c6af0f0d72e4c29a504e44aa4acf2dc", - "parentId": "fld_9dceb37ce1154d0095a71bdb36fe4a79", + "_id": "req_bf8fdccfac4141ea871c41d4f7403f5c", + "parentId": "fld_187756e90d514741a65cb9617a3ea41a", "modified": 1705942077015, "created": 1680682418204, "url": "{{ _.SEMANTIC_HUB_URL }}/hub/api/v1/models/urn%3Abamm%3Aio.catenax.serial_part_typization%3A1.0.0%23SerialPartTypization", @@ -2194,6 +2249,7 @@ }, "metaSortKey": -1680682418204, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2203,8 +2259,8 @@ "_type": "request" }, { - "_id": "req_f205a27f8073450cbde5e0398b48bde6", - "parentId": "fld_9dceb37ce1154d0095a71bdb36fe4a79", + "_id": "req_fb25cdceae984425b3aa867c3d5ea866", + "parentId": "fld_187756e90d514741a65cb9617a3ea41a", "modified": 1705942085733, "created": 1680682418192, "url": "{{ _.SEMANTIC_HUB_URL }}/hub/api/v1/models/urn%3Abamm%3Aio.catenax.serial_part_typization%3A1.0.0%23SerialPartTypization/json-schema", @@ -2223,6 +2279,7 @@ }, "metaSortKey": -1680682418192, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2232,8 +2289,8 @@ "_type": "request" }, { - "_id": "req_93454fd3c1084d399b3c2905cee98912", - "parentId": "fld_99d07b61e21942fab3999ca3411b6309", + "_id": "req_fad2ca6d902f401da947308e36bb22ff", + "parentId": "fld_26b4903278b54dc5a940fe28e4dd200a", "modified": 1705942100313, "created": 1680682418174, "url": "{{ _.BPDM_URL }}/v1/api/catena/business-partner/{% prompt 'BPN', '', '', '', false, true %}", @@ -2258,6 +2315,7 @@ }, "metaSortKey": -1680682418174, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2267,8 +2325,8 @@ "_type": "request" }, { - "_id": "fld_99d07b61e21942fab3999ca3411b6309", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_26b4903278b54dc5a940fe28e4dd200a", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1680682418184, "created": 1680682418184, "name": "Business partner data management", @@ -2279,8 +2337,8 @@ "_type": "request_group" }, { - "_id": "req_88256dff324a428fa91d114a88fcd3b4", - "parentId": "fld_97350fd0ea8c496caae4a2ed9eb74c5c", + "_id": "req_1b203a87420e42d5ba75c662ac8f49ee", + "parentId": "fld_048a4c04d1c4419683cb645279444127", "modified": 1702991347797, "created": 1680682418157, "url": "{{IRS_HOST}}/esr/esr-statistics/{% prompt 'globalAssetId', 'Provide global asset ID or use default', _.GLOBAL_ASSET_ID, '', false, true %}/{% prompt 'BOM Lifecycle', '', '', '', false, true %}/{% prompt 'Certificate', '', '', '', false, true %}/submodel", @@ -2304,6 +2362,7 @@ }, "metaSortKey": -1680682418158, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2313,8 +2372,8 @@ "_type": "request" }, { - "_id": "fld_97350fd0ea8c496caae4a2ed9eb74c5c", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_048a4c04d1c4419683cb645279444127", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1680682418167, "created": 1680682418167, "name": "ESR Spike", @@ -2325,8 +2384,8 @@ "_type": "request_group" }, { - "_id": "req_7872f416ad5349db9fbc8198a93438f0", - "parentId": "fld_a374a4f655934a47a494ab91e5ed46e3", + "_id": "req_32cc185810924d6cba6bb783422e919e", + "parentId": "fld_c645034b945b4aa5a34f15c60be2b27c", "modified": 1702991361578, "created": 1680682418143, "url": "{{IRS_HOST}}/ess/bpn/investigations", @@ -2353,6 +2412,7 @@ }, "metaSortKey": -1680682418143, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2362,8 +2422,8 @@ "_type": "request" }, { - "_id": "fld_a374a4f655934a47a494ab91e5ed46e3", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_c645034b945b4aa5a34f15c60be2b27c", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1680682418151, "created": 1680682418151, "name": "ESS Spike", @@ -2374,8 +2434,8 @@ "_type": "request_group" }, { - "_id": "req_88afb1555cd1418a9fed7524d2cfe286", - "parentId": "fld_a374a4f655934a47a494ab91e5ed46e3", + "_id": "req_818115f180424cc287bc730453851346", + "parentId": "fld_c645034b945b4aa5a34f15c60be2b27c", "modified": 1705942138125, "created": 1680682418134, "url": "{{IRS_HOST}}/ess/bpn/investigations/{% response 'body', 'req_ec674952c1114bce8fb71ea1ed6d9ef7', 'b64::JC5pZA==::46b', 'never', 60 %}", @@ -2399,6 +2459,7 @@ }, "metaSortKey": -1680682418138.5, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2408,8 +2469,8 @@ "_type": "request" }, { - "_id": "req_d2307da1ffaa4cee95303f073e8e8025", - "parentId": "fld_a374a4f655934a47a494ab91e5ed46e3", + "_id": "req_2a5fb997e87c439c8d2d75b1278bae3f", + "parentId": "fld_c645034b945b4aa5a34f15c60be2b27c", "modified": 1702991370481, "created": 1680682418134, "url": "{{IRS_HOST}}/ess/bpn/investigations/{% prompt 'Job ID', '', '', '', false, true %}", @@ -2433,6 +2494,7 @@ }, "metaSortKey": -1680682418134, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2442,8 +2504,8 @@ "_type": "request" }, { - "_id": "req_8890c0b2034c48769d06fdefdd8ad27d", - "parentId": "fld_960ae2d3cdb6470a84ae4836eb497c41", + "_id": "req_09e428687b484535af82e17dbf9a68bf", + "parentId": "fld_9b6334cef97a427195690af454455820", "modified": 1710076303275, "created": 1680682418118, "url": "{{IRS_HOST}}/irs/orders", @@ -2470,6 +2532,7 @@ }, "metaSortKey": -1680682418118, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2479,8 +2542,8 @@ "_type": "request" }, { - "_id": "fld_960ae2d3cdb6470a84ae4836eb497c41", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_9b6334cef97a427195690af454455820", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1680682418128, "created": 1680682418128, "name": "Batch Processing", @@ -2491,8 +2554,8 @@ "_type": "request_group" }, { - "_id": "req_899fdffe97094ec1b8360b09ff7f19e4", - "parentId": "fld_960ae2d3cdb6470a84ae4836eb497c41", + "_id": "req_cfe969099893477d95f7f654a588750a", + "parentId": "fld_9b6334cef97a427195690af454455820", "modified": 1702991390349, "created": 1696342619602, "url": "{{IRS_HOST}}/irs/ess/orders", @@ -2519,6 +2582,7 @@ }, "metaSortKey": -1680682418113.5, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2528,8 +2592,8 @@ "_type": "request" }, { - "_id": "req_500399b00f1c4beba49bb0d416693873", - "parentId": "fld_960ae2d3cdb6470a84ae4836eb497c41", + "_id": "req_9aca2c0b52564e64b266ecf2ef22d5e0", + "parentId": "fld_9b6334cef97a427195690af454455820", "modified": 1705006936944, "created": 1705006139836, "url": "{{IRS_HOST}}/irs/orders/{% prompt 'Order ID', '', '', '', false, true %}", @@ -2557,6 +2621,7 @@ }, "metaSortKey": -1680682418111.25, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2566,8 +2631,8 @@ "_type": "request" }, { - "_id": "req_e5c9453b6ca4432dbc41f0719ebc10ee", - "parentId": "fld_960ae2d3cdb6470a84ae4836eb497c41", + "_id": "req_55a45adbf0c9488ab2c912b92a49a103", + "parentId": "fld_9b6334cef97a427195690af454455820", "modified": 1702991398473, "created": 1680682418109, "url": "{{IRS_HOST}}/irs/orders/{% prompt 'Order ID', '', '', '', false, true %}", @@ -2591,6 +2656,7 @@ }, "metaSortKey": -1680682418109, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2600,8 +2666,8 @@ "_type": "request" }, { - "_id": "req_17ef91cf95974a88ab1ea3caac512f2e", - "parentId": "fld_960ae2d3cdb6470a84ae4836eb497c41", + "_id": "req_c2b63b7133fb460db0f6289b75733bc6", + "parentId": "fld_9b6334cef97a427195690af454455820", "modified": 1702991409664, "created": 1680682418099, "url": "{{IRS_HOST}}/irs/orders/{% prompt 'Order ID', '', '', '', false, true %}/batches/{% prompt 'Batch ID', '', '', '', false, true %}", @@ -2625,6 +2691,7 @@ }, "metaSortKey": -1680682418099, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2634,8 +2701,8 @@ "_type": "request" }, { - "_id": "req_4c99e0188bee4399b5b835473f5faf0c", - "parentId": "fld_b3e64009f73b4de58102f62dfddee9da", + "_id": "req_b74cc6344b7c4388b96656993b172d46", + "parentId": "fld_46a973a72ee54858be7b730077f4a0c6", "modified": 1690472186478, "created": 1678358655308, "url": "{{ _.CONSUMER_CONTROLPLANE }}/management/v2/catalog/request", @@ -2662,6 +2729,7 @@ }, "metaSortKey": -1686195722939.1875, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2671,8 +2739,8 @@ "_type": "request" }, { - "_id": "fld_b3e64009f73b4de58102f62dfddee9da", - "parentId": "fld_64cab3b2c6fd483e87208b3ff434a03e", + "_id": "fld_46a973a72ee54858be7b730077f4a0c6", + "parentId": "fld_0b9d0531ef3e49efa333cd21a78f8c94", "modified": 1690362660167, "created": 1690362660167, "name": "Catalog", @@ -2683,8 +2751,8 @@ "_type": "request_group" }, { - "_id": "fld_64cab3b2c6fd483e87208b3ff434a03e", - "parentId": "fld_ddabc30cc3ff4b70a7401bcc81101f8f", + "_id": "fld_0b9d0531ef3e49efa333cd21a78f8c94", + "parentId": "fld_7b1b2f5f85934d3d8c82d7c7ce458380", "modified": 1690363778601, "created": 1675675609576, "name": "EDC-Requests", @@ -2695,8 +2763,8 @@ "_type": "request_group" }, { - "_id": "req_3c34357d0ea04bccb4b6213f492673cc", - "parentId": "fld_b3e64009f73b4de58102f62dfddee9da", + "_id": "req_73691ed276bd4771a5f9504075648a79", + "parentId": "fld_46a973a72ee54858be7b730077f4a0c6", "modified": 1691500654267, "created": 1685521485278, "url": "{{ _.CONSUMER_CONTROLPLANE }}/management/v2/catalog/request", @@ -2723,6 +2791,7 @@ }, "metaSortKey": -1686195722889.1875, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2732,8 +2801,8 @@ "_type": "request" }, { - "_id": "req_36dd4e98c75b43dcac15252ad1b05469", - "parentId": "fld_b3e64009f73b4de58102f62dfddee9da", + "_id": "req_f063f58ce17c4c04bcd9e8feea08027c", + "parentId": "fld_46a973a72ee54858be7b730077f4a0c6", "modified": 1705940987109, "created": 1691654388376, "url": "{{ _.CONSUMER_CONTROLPLANE }}/management/v2/catalog/request", @@ -2760,6 +2829,7 @@ }, "metaSortKey": -1686195722789.1875, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2769,8 +2839,8 @@ "_type": "request" }, { - "_id": "req_b1080c0e01e640afad06e99a8e9c6256", - "parentId": "fld_04c0afc0cea94d8e94c1539812d7f8f9", + "_id": "req_5eb26ad544f147b9a6f145a931e9f500", + "parentId": "fld_f1b0ee70bb2d45b7a32a643ab9a3d1d4", "modified": 1691578280640, "created": 1675675609557, "url": "{{ _.CONSUMER_CONTROLPLANE }}/management/v2/contractnegotiations", @@ -2797,6 +2867,7 @@ }, "metaSortKey": -1684146511095, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2806,8 +2877,8 @@ "_type": "request" }, { - "_id": "fld_04c0afc0cea94d8e94c1539812d7f8f9", - "parentId": "fld_64cab3b2c6fd483e87208b3ff434a03e", + "_id": "fld_f1b0ee70bb2d45b7a32a643ab9a3d1d4", + "parentId": "fld_0b9d0531ef3e49efa333cd21a78f8c94", "modified": 1684146626847, "created": 1684146519491, "name": "Negotiation", @@ -2818,8 +2889,8 @@ "_type": "request_group" }, { - "_id": "req_56247bd1dd154ba5b925d7c2347adbb8", - "parentId": "fld_04c0afc0cea94d8e94c1539812d7f8f9", + "_id": "req_4fced7f1dd1c40b3b7ff236a89f1922e", + "parentId": "fld_f1b0ee70bb2d45b7a32a643ab9a3d1d4", "modified": 1690362123962, "created": 1675675609549, "url": "{{ _.CONSUMER_CONTROLPLANE }}/management/v2/contractnegotiations/{% prompt 'id', '', '', '', false, true %}", @@ -2843,6 +2914,7 @@ }, "metaSortKey": -1684146511045, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2852,8 +2924,8 @@ "_type": "request" }, { - "_id": "req_61c7b18918854333bf64b6b2a7d30a0e", - "parentId": "fld_04c0afc0cea94d8e94c1539812d7f8f9", + "_id": "req_e62636f85f0d48d6bfb21a16602eacda", + "parentId": "fld_f1b0ee70bb2d45b7a32a643ab9a3d1d4", "modified": 1690362117725, "created": 1685444139708, "url": "{{ _.CONSUMER_CONTROLPLANE }}/management/v2/contractnegotiations/{% prompt 'id', '', '', '', false, true %}/cancel", @@ -2872,6 +2944,7 @@ }, "metaSortKey": -1684146511020, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2881,8 +2954,8 @@ "_type": "request" }, { - "_id": "req_bb6f0b86fcdc45e190c8295415554a19", - "parentId": "fld_04c0afc0cea94d8e94c1539812d7f8f9", + "_id": "req_d0b90529e95545af8d9f6ef234d64670", + "parentId": "fld_f1b0ee70bb2d45b7a32a643ab9a3d1d4", "modified": 1690361721223, "created": 1681911985730, "url": "{{ _.CONSUMER_CONTROLPLANE }}/management/v2/contractnegotiations/request", @@ -2909,6 +2982,7 @@ }, "metaSortKey": -1684146510995, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2918,8 +2992,8 @@ "_type": "request" }, { - "_id": "req_64bfc1e19445477497857f7e4573cf65", - "parentId": "fld_04c0afc0cea94d8e94c1539812d7f8f9", + "_id": "req_7ef28b43bb8444728eb0bedaf8af2111", + "parentId": "fld_f1b0ee70bb2d45b7a32a643ab9a3d1d4", "modified": 1691578311420, "created": 1675675609541, "url": "{{ _.CONSUMER_CONTROLPLANE }}/management/v2/transferprocesses", @@ -2946,6 +3020,7 @@ }, "metaSortKey": -1684146510945, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2955,8 +3030,8 @@ "_type": "request" }, { - "_id": "req_fa5e5cf564a74c8c9a804b7b2b8963e2", - "parentId": "fld_04c0afc0cea94d8e94c1539812d7f8f9", + "_id": "req_04d6350cd308435589ff2d8fb6bb01dc", + "parentId": "fld_f1b0ee70bb2d45b7a32a643ab9a3d1d4", "modified": 1691503370103, "created": 1679993996270, "url": "{{ _.CONSUMER_CONTROLPLANE }}/management/v2/transferprocesses/{% prompt 'id', '', '', '', false, true %}", @@ -2980,6 +3055,7 @@ }, "metaSortKey": -1684146510895, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -2989,8 +3065,8 @@ "_type": "request" }, { - "_id": "req_b8f90634a5944b348ea9494c7f17b6a8", - "parentId": "fld_04c0afc0cea94d8e94c1539812d7f8f9", + "_id": "req_4ec26c1537ed4c66ac8d6da53a506c71", + "parentId": "fld_f1b0ee70bb2d45b7a32a643ab9a3d1d4", "modified": 1690361795179, "created": 1675675609525, "url": "{{ _.CONSUMER_CONTROLPLANE }}/management/v2/transferprocesses/request", @@ -3017,6 +3093,7 @@ }, "metaSortKey": -1684146510845, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3026,8 +3103,8 @@ "_type": "request" }, { - "_id": "req_edcebfca1e5a40d6b7f2d99e74db43c3", - "parentId": "fld_04c0afc0cea94d8e94c1539812d7f8f9", + "_id": "req_0d7af3abbb194ed191e482b9b857070e", + "parentId": "fld_f1b0ee70bb2d45b7a32a643ab9a3d1d4", "modified": 1690361763512, "created": 1681910653593, "url": "{{CONSUMER_CONTROLPLANE}}/management/v2/contractagreements/request", @@ -3054,6 +3131,7 @@ }, "metaSortKey": -1684146510795, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3063,8 +3141,8 @@ "_type": "request" }, { - "_id": "req_317357c37d724aa2a25d2243ec444e31", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_633a776c22914478a6899c6f2f757d8e", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690362947546, "created": 1681907482278, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/assets", @@ -3091,6 +3169,7 @@ }, "metaSortKey": -1679911033461.75, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3100,8 +3179,8 @@ "_type": "request" }, { - "_id": "fld_8990e7651c904d5aa52f4c1c0981a60a", - "parentId": "fld_64cab3b2c6fd483e87208b3ff434a03e", + "_id": "fld_ca5fb2ce9c5a4640b827916773279500", + "parentId": "fld_0b9d0531ef3e49efa333cd21a78f8c94", "modified": 1705940929752, "created": 1684146457388, "name": "Provider", @@ -3112,8 +3191,8 @@ "_type": "request_group" }, { - "_id": "req_570c4a14d7db43a18d296cb11f1a1cee", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_52d9308387b04d60a06b43ee1c492478", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690362407763, "created": 1685444139630, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/assets/{% prompt 'id', '', '', '', false, true %}", @@ -3132,6 +3211,7 @@ }, "metaSortKey": -1679911033452.375, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3141,8 +3221,8 @@ "_type": "request" }, { - "_id": "req_c4df9110e0a345cc95afe85a30eac32b", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_1ae8b300301b406eb545df43a353fda9", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690362438115, "created": 1685444139625, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/assets/request", @@ -3169,6 +3249,7 @@ }, "metaSortKey": -1679911033447.6875, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3178,8 +3259,8 @@ "_type": "request" }, { - "_id": "req_0bc18af3230d4046b3e805ad47d7a86d", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_9eff358d42094196924ab55c23d7510d", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690362400081, "created": 1685444139636, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/assets/{% prompt 'id', '', '', '', false, true %}", @@ -3198,6 +3279,7 @@ }, "metaSortKey": -1679911033433.625, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3207,8 +3289,8 @@ "_type": "request" }, { - "_id": "req_bf080627d91545438cb460ad078fc01a", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_5fd712c0594d4b46a349bb56dae21809", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690362581978, "created": 1685444139641, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/policydefinitions", @@ -3235,6 +3317,7 @@ }, "metaSortKey": -1679911033403.9375, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3244,8 +3327,8 @@ "_type": "request" }, { - "_id": "req_06b8fed2305945deafe7dd173618e440", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_8b5ce92a1e96425e8353aba23643cd6b", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690362549290, "created": 1685444139647, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/policydefinitions/{% prompt 'id', '', '', '', false, true %}", @@ -3262,8 +3345,9 @@ "value": "{{ _.EDC_API_KEY }}", "addTo": "header" }, - "metaSortKey": -1679911033364.0937, + "metaSortKey": -1679911033364.0938, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3273,8 +3357,8 @@ "_type": "request" }, { - "_id": "req_ab6433968d444c4fb3980000d98c177e", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_274c9ac5236046919dd4bb71af15dd62", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690362591799, "created": 1685444139653, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/policydefinitions/request", @@ -3301,6 +3385,7 @@ }, "metaSortKey": -1679911033344.1719, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3310,8 +3395,8 @@ "_type": "request" }, { - "_id": "req_2d58d303468d4b42bc2943873356836c", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_e5e4eaf35c7545d7aaacf2388e2a42fc", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690362559324, "created": 1685444139659, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/policydefinitions/{% prompt 'id', '', '', '', false, true %}", @@ -3330,6 +3415,7 @@ }, "metaSortKey": -1679911033299.25, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3339,8 +3425,8 @@ "_type": "request" }, { - "_id": "req_c7751e7ea2a343a1bfdf5a7391d8b1e8", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_92959d74ff4f475b8e357e4958b1c457", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690363080444, "created": 1685444139665, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/contractdefinitions", @@ -3367,6 +3453,7 @@ }, "metaSortKey": -1679911033261.75, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3376,8 +3463,8 @@ "_type": "request" }, { - "_id": "req_4dbe36f239974916b8328f92025f7079", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_3de985b534fd4b23ad77e45e40126706", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690362691392, "created": 1685444139672, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/contractdefinitions/{% prompt 'id', '', '', '', false, true %}", @@ -3396,6 +3483,7 @@ }, "metaSortKey": -1679911033199.25, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3405,8 +3493,8 @@ "_type": "request" }, { - "_id": "req_b6e1779d1fd74edfa3e9861e5a2f85b4", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_730967ca2ad2470bab0d047f7491c460", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690363126919, "created": 1685444139678, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/contractdefinitions/request", @@ -3433,6 +3521,7 @@ }, "metaSortKey": -1679911033174.25, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3442,8 +3531,8 @@ "_type": "request" }, { - "_id": "req_0841b47dec974e11a2ec9db073fb6af0", - "parentId": "fld_8990e7651c904d5aa52f4c1c0981a60a", + "_id": "req_b200c2519b814e159bdde39fd86690a2", + "parentId": "fld_ca5fb2ce9c5a4640b827916773279500", "modified": 1690363136216, "created": 1685444139684, "url": "{{ _.PROVIDER_CONTROLPLANE_1 }}/management/v2/contractdefinitions/{% prompt 'id', '', '', '', false, true %}", @@ -3470,6 +3559,7 @@ }, "metaSortKey": -1679911033149.25, "isPrivate": false, + "pathParameters": [], "settingStoreCookies": true, "settingSendCookies": true, "settingDisableRenderRequestBody": false, @@ -3479,8 +3569,8 @@ "_type": "request" }, { - "_id": "env_d2b7eb1621841465ea24b73343568b286aa8ac9a", - "parentId": "wrk_565df8abe30f4da29d8bffcde97927d7", + "_id": "env_a3894a0a395c481d84f1126ba07bb47c", + "parentId": "wrk_d83bab75184e43adadd63001907af70d", "modified": 1680782486844, "created": 1680782486844, "name": "Base Environment", @@ -3492,8 +3582,8 @@ "_type": "environment" }, { - "_id": "jar_d2b7eb1621841465ea24b73343568b286aa8ac9a", - "parentId": "wrk_565df8abe30f4da29d8bffcde97927d7", + "_id": "jar_13d0657e04f54f6ab1e9903f108f0841", + "parentId": "wrk_d83bab75184e43adadd63001907af70d", "modified": 1709815397125, "created": 1680782486851, "name": "Default Jar", @@ -3530,26 +3620,6 @@ } ], "_type": "cookie_jar" - }, - { - "_id": "spc_22dfe33611af4731965cc2b08febcfdb", - "parentId": "wrk_565df8abe30f4da29d8bffcde97927d7", - "modified": 1680782484284, - "created": 1680782484284, - "fileName": "IRS", - "contents": "", - "contentType": "yaml", - "_type": "api_spec" - }, - { - "_id": "spc_3a573993100a40b3bc2b0a5bd8e5cc48", - "parentId": "wrk_565df8abe30f4da29d8bffcde97927d7", - "modified": 1681726479575, - "created": 1681726479575, - "fileName": "IRS", - "contents": "", - "contentType": "yaml", - "_type": "api_spec" } ] } \ No newline at end of file diff --git a/pom.xml b/pom.xml index c7194ecc39..74d3eefb49 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ 1.7.0-SNAPSHOT - 3.1.9 + 3.1.10 2.2.0 1.11.4 1.9.0