|
1 | | - |
2 | | - |
| 1 | +# Support for a Central Marketplace |
3 | 2 |
|
4 | | -1. A Provider employee registers the marketplace in the Provider: |
| 3 | +Various Data Space Use-Cases require a solution for offering services through a central Marketplace, in order to lower requirements for participants and improve visibility of their offerings. |
5 | 4 |
|
6 | | - 1.1. As a trusted-issuer of credentials("MarketplaceCredential") required to send notifications |
| 5 | +## Architecture |
7 | 6 |
|
8 | | - * check if Gaia-X credential for that purpose exists |
9 | 7 |
|
10 | | - 1.2. Register policies that allow the marketplace to send order notifications to the Contract-Management |
| 8 | + |
11 | 9 |
|
12 | | - * should f.e. check the offer-id |
| 10 | +Integration of Participants into a Central Marketplace happens through the same mechanisms and components as the normal [marketplace integration](MARKETPLACE_INTEGRATION.md). |
| 11 | +Particpants offering their services on the Central Marketplace are required to provide an instance of the [ContractManagement](https://github.com/FIWARE/contract-management). The Central Marketplace also runs the Contract Management Component and manages Organizations, Products and Offerings through the TMForum API. |
13 | 12 |
|
14 | | -2. Provider employee creates the product-offering at the BAE-Marketplace |
| 13 | +The basic flow of integration is as following: |
15 | 14 |
|
16 | | -* needs to contain the Providers Contract-Management address -> Options: "place"/"channel" in offering, "productSpecCharacteristic" in spec |
| 15 | +1. The Data Provider has to prepare its integration by: |
17 | 16 |
|
18 | | -* needs to contain accessible endpoints for the customer(same options) |
| 17 | + 1.1. Register the Marketplace as a trusted-issuer of credentials used by the Contract Management |
| 18 | + 1.2. Register policies that allow the marketplace to send order notifications to the Contract-Management(see [allowContractManagement.json](../it/src/test/resources/policies/allowContractManagement.json) as an example) |
| 19 | + 1.3 Provider has to register itself at the Central Marketplace as an Oranization, containing access information to the Contract Management |
19 | 20 |
|
20 | | -3. Customer buys access at the BAE-Marketplace |
| 21 | +2. Create Product Offering |
21 | 22 |
|
22 | | -* BAE interacts with TMForum |
23 | | -* Contract-Management(Marketplace) receives notifications from TMForum |
| 23 | +3. Customer buys access at the Marketplace |
24 | 24 |
|
25 | 25 | 4. Contract Management sends notifcation to the Providers Contract-Management |
26 | 26 |
|
27 | | - 4.1. Authenticates with VC at the verifier |
28 | | - |
29 | | - * Credential could either be pre-issued, created via library or a helper component -> to be decided |
30 | | - |
| 27 | + 4.1. Authenticates with the Verifiable Credential configured in 1.1 at the verifier |
31 | 28 | 4.2. Send order notifications to the Contract-Management(through PEP) |
32 | 29 |
|
33 | 30 | 5. Contract-Management activates the service: |
34 | 31 |
|
35 | 32 | 5.1. Adds the customer to the trusted-issuers-list(according to the order) |
36 | | - |
37 | 33 | 5.2. Creates the policies from the order |
38 | 34 |
|
39 | | -Open: |
| 35 | +## Demo |
| 36 | + |
| 37 | +In order to run the Demo flows, the [Local Deployment](./deployment-integration/local-deployment/LOCAL.MD) has to be prepared. |
| 38 | +In the Demo-Scenario, the Consumer-Organization("fancy-marketplace.biz") also acts as the provider of the centralized marketplace, while the Provider-Organization("mp-operations.org") offers its services through that market. |
| 39 | + |
| 40 | +### Prepare the marketplace |
| 41 | + |
| 42 | +Register the policies required to restrict access to the TMForum. Only Users in the Role "REPRESENTATIVE" should be allowed to interact with it. |
| 43 | + |
| 44 | +```shell |
| 45 | + ./doc/scripts/prepare-central-market-policies.sh |
| 46 | +``` |
| 47 | + |
| 48 | +### Prepare the provider [(Step 1)](#architecture) |
| 49 | + |
| 50 | +Create a policy, restricting access to the Contract Management to requests authenticated with a "MarketplaceCredential" |
40 | 51 |
|
41 | | -* notify product to the provider -> handling of cancellation etc.? |
| 52 | +```shell |
| 53 | +# Allow contract management access at the provider side |
| 54 | +curl -X 'POST' http://pap-provider.127.0.0.1.nip.io:8080/policy \ |
| 55 | + -H 'Content-Type: application/json' \ |
| 56 | + -d "$(cat ./it/src/test/resources/policies/allowContractManagement.json)" |
| 57 | +``` |
42 | 58 |
|
43 | | -1. Register the Provider at the Marketplace: |
| 59 | +Get a "LegalPersonCredential" for the Provider, containing the role "REPRESENTATIVE".(see [Provider` ClientScopes config](../k3s/provider.yaml#957)) |
44 | 60 |
|
45 | 61 | ```shell |
46 | | - export FANCY_MARKETPLACE_ID=$(curl -X POST http://mp-tmf-api.127.0.0.1.nip.io:8080/tmf-api/party/v4/organization \ |
| 62 | +export PROVIDER_USER_CREDENTIAL=$(./doc/scripts/get_credential.sh https://keycloak-provider.127.0.0.1.nip.io user-credential employee); echo ${PROVIDER_USER_CREDENTIAL} |
| 63 | +``` |
| 64 | + |
| 65 | +Register the Provider at the Marketplace, containing the address of the Contract Management and the required clientId/scope for authentication: |
| 66 | + |
| 67 | +```shell |
| 68 | + # set the Providers DID |
| 69 | + export PROVIDER_DID="did:web:mp-operations.org" |
| 70 | + # get an AccessToken for the Credential |
| 71 | + export ACCESS_TOKEN=$(./doc/scripts/get_access_token_oid4vp.sh http://fancy-marketplace.127.0.0.1.nip.io:8080 $PROVIDER_USER_CREDENTIAL default); echo $ACCESS_TOKEN |
| 72 | + # create the organization at the providers TMForum |
| 73 | + export MP_OPERATIONS_ID=$(curl -X POST http://fancy-marketplace.127.0.0.1.nip.io:8080/tmf-api/party/v4/organization \ |
47 | 74 | -H 'Accept: */*' \ |
48 | 75 | -H 'Content-Type: application/json' \ |
49 | 76 | -H "Authorization: Bearer ${ACCESS_TOKEN}" \ |
50 | 77 | -d "{ |
51 | | - \"name\": \"Fancy Marketplace Inc.\", |
| 78 | + \"name\": \"M&P Operations Org.\", |
52 | 79 | \"partyCharacteristic\": [ |
53 | 80 | { |
54 | 81 | \"name\": \"did\", |
55 | | - \"value\": \"${CONSUMER_DID}\" |
| 82 | + \"value\": \"${PROVIDER_DID}\" |
56 | 83 | }, |
57 | 84 | { |
58 | | - \"name\": \"contract-management\", |
| 85 | + \"name\": \"contractManagement\", |
59 | 86 | \"value\": { |
60 | | - \"address\": \"https://contract-management.data-provider.io\", |
| 87 | + \"address\": \"http://contract-management.127.0.0.1.nip.io:8080\", |
61 | 88 | \"clientId\":\"contract-management\", |
62 | | - // maybe |
63 | | - \"scope\": [\"openid\", \"external-marketplace\"] |
64 | | - }, |
65 | | - \"@schemaLocation\": \"to-be-created\" |
| 89 | + \"scope\": [\"external-marketplace\"] |
| 90 | + } |
66 | 91 | } |
67 | 92 | ] |
68 | | - }" | jq '.id' -r); echo ${FANCY_MARKETPLACE_ID} |
| 93 | + }" | jq '.id' -r); echo ${MP_OPERATIONS_ID} |
69 | 94 | ``` |
70 | 95 |
|
71 | | -2. Create specification, referencing the provider: |
| 96 | +### Create the Offering [(Step 2)](#architecture) |
| 97 | + |
| 98 | +Create product specification, referencing the provider: |
| 99 | + |
72 | 100 | ```shell |
73 | | - export PRODUCT_SPEC_FULL_ID=$(curl -X 'POST' http://tm-forum-api.127.0.0.1.nip.io:8080/tmf-api/productCatalogManagement/v4/productSpecification \ |
| 101 | + export ACCESS_TOKEN=$(./doc/scripts/get_access_token_oid4vp.sh http://fancy-marketplace.127.0.0.1.nip.io:8080 $PROVIDER_USER_CREDENTIAL default); echo $ACCESS_TOKEN |
| 102 | + export PRODUCT_SPEC=$(curl -X 'POST' http://fancy-marketplace.127.0.0.1.nip.io:8080/tmf-api/productCatalogManagement/v4/productSpecification \ |
| 103 | + -H 'Accept: */*' \ |
74 | 104 | -H 'Content-Type: application/json;charset=utf-8' \ |
| 105 | + -H "Authorization: Bearer ${ACCESS_TOKEN}" \ |
75 | 106 | -d "{ |
76 | 107 | \"brand\": \"M&P Operations\", |
77 | 108 | \"version\": \"1.0.0\", |
78 | 109 | \"lifecycleStatus\": \"ACTIVE\", |
79 | 110 | \"name\": \"M&P K8S\", |
80 | 111 | \"relatedParty\": [ |
81 | 112 | { |
82 | | - \"id\": \"${FANCY_MARKETPLACE_ID}\", |
| 113 | + \"id\": \"${MP_OPERATIONS_ID}\", |
83 | 114 | \"role\": \"provider\" |
84 | 115 | } |
85 | | - ] |
| 116 | + ], |
86 | 117 | \"productSpecCharacteristic\": [ |
87 | 118 | { |
88 | 119 | \"id\": \"credentialsConfig\", |
@@ -170,7 +201,128 @@ Open: |
170 | 201 | ] |
171 | 202 | } |
172 | 203 | ] |
173 | | - }" | jq '.id' -r ); echo ${PRODUCT_SPEC_FULL_ID} |
| 204 | + }" | jq '.id' -r ); echo ${PRODUCT_SPEC} |
| 205 | +``` |
| 206 | + |
| 207 | +Create product offering, referencing the product spec: |
| 208 | + |
| 209 | +```shell |
| 210 | + export ACCESS_TOKEN=$(./doc/scripts/get_access_token_oid4vp.sh http://fancy-marketplace.127.0.0.1.nip.io:8080 $PROVIDER_USER_CREDENTIAL default); echo $ACCESS_TOKEN |
| 211 | + export PRODUCT_OFFERING_ID=$(curl -X 'POST' http://fancy-marketplace.127.0.0.1.nip.io:8080/tmf-api/productCatalogManagement/v4/productOffering \ |
| 212 | + -H 'Accept: */*' \ |
| 213 | + -H 'Content-Type: application/json;charset=utf-8' \ |
| 214 | + -H "Authorization: Bearer ${ACCESS_TOKEN}" \ |
| 215 | + -d "{ |
| 216 | + \"version\": \"1.0.0\", |
| 217 | + \"lifecycleStatus\": \"ACTIVE\", |
| 218 | + \"name\": \"M&P K8S Offering\", |
| 219 | + \"productSpecification\": { |
| 220 | + \"id\": \"${PRODUCT_SPEC}\" |
| 221 | + } |
| 222 | + }" | jq '.id' -r ); echo ${PRODUCT_OFFERING_ID} |
| 223 | +``` |
| 224 | + |
| 225 | + |
| 226 | +### Buy access to the offering [(Step 2)](#architecture) |
| 227 | + |
| 228 | +In order to keep the demo environment manageable, the Consumer-Organization will buy access to the Providers offering: |
| 229 | + |
| 230 | +Create a UserCredential for the consumer: |
| 231 | + |
| 232 | +```shell |
| 233 | +export CONSUMER_USER_CREDENTIAL=$(./doc/scripts/get_credential.sh https://keycloak-consumer.127.0.0.1.nip.io user-sd employee vc+sd-jwt); echo ${CONSUMER_USER_CREDENTIAL} |
| 234 | +``` |
| 235 | +Create an OperatorCredential for the consumer: |
| 236 | + |
| 237 | +```shell |
| 238 | +export CONSUMER_OPERATOR_CREDENTIAL=$(./doc/scripts/get_credential.sh https://keycloak-consumer.127.0.0.1.nip.io operator-credential operator); echo ${CONSUMER_OPERATOR_CREDENTIAL} |
| 239 | +``` |
| 240 | + |
| 241 | +Assert that access is not yet possible(e.g. the Consumer cannot get an AccessToken for the OperatorCredential): |
| 242 | + |
| 243 | +```shell |
| 244 | + export ACCESS_TOKEN=$(./doc/scripts/get_access_token_oid4vp.sh http://mp-data-service.127.0.0.1.nip.io:8080 $CONSUMER_OPERATOR_CREDENTIAL operator); echo ${ACCESS_TOKEN} |
| 245 | +``` |
| 246 | + |
| 247 | +Now register "fancy-marketplace.biz" as a Consumer at the Marketplace: |
| 248 | + |
| 249 | +Register Fancy Marketplace as a Consumer |
| 250 | +```shell |
| 251 | + # set the Consumer DID |
| 252 | + export CONSUMER_DID="did:web:fancy-marketplace.biz" |
| 253 | + # get an access token for the UserCredential |
| 254 | + export ACCESS_TOKEN=$(./doc/scripts/get_access_token_oid4vp.sh http://fancy-marketplace.127.0.0.1.nip.io:8080 $CONSUMER_USER_CREDENTIAL default); echo ${ACCESS_TOKEN} |
| 255 | + # register fancy-marketplace.biz as an organization(no need for a contract-management address in the consumer) |
| 256 | + export FANCY_MARKETPLACE_ID=$(curl -X POST http://fancy-marketplace.127.0.0.1.nip.io:8080/tmf-api/party/v4/organization \ |
| 257 | + -H 'Accept: */*' \ |
| 258 | + -H 'Content-Type: application/json' \ |
| 259 | + -H "Authorization: Bearer ${ACCESS_TOKEN}" \ |
| 260 | + -d "{ |
| 261 | + \"name\": \"Fancy Marketplace Inc.\", |
| 262 | + \"partyCharacteristic\": [ |
| 263 | + { |
| 264 | + \"name\": \"did\", |
| 265 | + \"value\": \"${CONSUMER_DID}\" |
| 266 | + } |
| 267 | + ] |
| 268 | + }" | jq '.id' -r); echo ${FANCY_MARKETPLACE_ID} |
174 | 269 | ``` |
175 | 270 |
|
176 | | --> CM extracts spec and provider from the order, extract CM information from org |
| 271 | +List the offerings of the marketplace, only one should be registered at the moment: |
| 272 | + |
| 273 | +```shell |
| 274 | + export ACCESS_TOKEN=$(./doc/scripts/get_access_token_oid4vp.sh http://fancy-marketplace.127.0.0.1.nip.io:8080 $CONSUMER_USER_CREDENTIAL default); echo $ACCESS_TOKEN |
| 275 | + curl -X GET http://fancy-marketplace.127.0.0.1.nip.io:8080/tmf-api/productCatalogManagement/v4/productOffering -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq . |
| 276 | +``` |
| 277 | + |
| 278 | + |
| 279 | +Extract the OfferId from the TMForum API: |
| 280 | +```shell |
| 281 | + export ACCESS_TOKEN=$(./doc/scripts/get_access_token_oid4vp.sh http://fancy-marketplace.127.0.0.1.nip.io:8080 $CONSUMER_USER_CREDENTIAL default); echo $ACCESS_TOKEN |
| 282 | + export OFFER_ID=$(curl -X GET http://fancy-marketplace.127.0.0.1.nip.io:8080/tmf-api/productCatalogManagement/v4/productOffering -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq '.[0].id' -r); echo ${OFFER_ID} |
| 283 | +``` |
| 284 | + |
| 285 | +Create an order for the offering: |
| 286 | +```shell |
| 287 | + export ACCESS_TOKEN=$(./doc/scripts/get_access_token_oid4vp.sh http://fancy-marketplace.127.0.0.1.nip.io:8080 $CONSUMER_USER_CREDENTIAL default); echo $ACCESS_TOKEN |
| 288 | + export ORDER_ID=$(curl -X POST http://fancy-marketplace.127.0.0.1.nip.io:8080/tmf-api/productOrderingManagement/v4/productOrder \ |
| 289 | + -H 'Accept: */*' \ |
| 290 | + -H 'Content-Type: application/json' \ |
| 291 | + -H "Authorization: Bearer ${ACCESS_TOKEN}" \ |
| 292 | + -d "{ |
| 293 | + \"productOrderItem\": [ |
| 294 | + { |
| 295 | + \"id\": \"random-order-id\", |
| 296 | + \"action\": \"add\", |
| 297 | + \"productOffering\": { |
| 298 | + \"id\" : \"${OFFER_ID}\" |
| 299 | + } |
| 300 | + } |
| 301 | + ], |
| 302 | + \"relatedParty\": [ |
| 303 | + { |
| 304 | + \"id\": \"${FANCY_MARKETPLACE_ID}\" |
| 305 | + } |
| 306 | + ]}" | jq '.id' -r); echo ${ORDER_ID} |
| 307 | +``` |
| 308 | + |
| 309 | +Complete the order: |
| 310 | +```shell |
| 311 | + export ACCESS_TOKEN=$(./doc/scripts/get_access_token_oid4vp.sh http://fancy-marketplace.127.0.0.1.nip.io:8080 $CONSUMER_USER_CREDENTIAL default); echo $ACCESS_TOKEN |
| 312 | + curl -X 'PATCH' \ |
| 313 | + -H "Authorization: Bearer ${ACCESS_TOKEN}" \ |
| 314 | + http://fancy-marketplace.127.0.0.1.nip.io:8080/tmf-api/productOrderingManagement/v4/productOrder/${ORDER_ID} \ |
| 315 | + -H 'accept: application/json;charset=utf-8' \ |
| 316 | + -H 'Content-Type: application/json;charset=utf-8' \ |
| 317 | + -d "{ |
| 318 | + \"state\": \"completed\" |
| 319 | + }" | jq . |
| 320 | +``` |
| 321 | + |
| 322 | +Once the order is completed, the Contract Management of the Marketplace will send a notification to the Providers Contract Management, where the credential configuration and policies from the product will be applied to the Trusted Issuers List and the PAP. |
| 323 | + |
| 324 | +Now it should be possible to get an AccessToken for the Consumer's OperatorCredential: |
| 325 | + |
| 326 | +```shell |
| 327 | + export ACCESS_TOKEN=$(./doc/scripts/get_access_token_oid4vp.sh http://mp-data-service.127.0.0.1.nip.io:8080 $CONSUMER_OPERATOR_CREDENTIAL operator); echo ${ACCESS_TOKEN} |
| 328 | +``` |
0 commit comments