Skip to content
This repository has been archived by the owner on Sep 19, 2024. It is now read-only.

Commit

Permalink
docs: section about contract negotiations (#182)
Browse files Browse the repository at this point in the history
* docs: section about contract negotiations

* Update developer/wip/for-contributors/contributor-handbook.md

Co-authored-by: Paul Latzelsperger <[email protected]>

* Update developer/wip/for-contributors/contributor-handbook.md

Co-authored-by: Paul Latzelsperger <[email protected]>

* pr suggestions

---------

Co-authored-by: Paul Latzelsperger <[email protected]>
  • Loading branch information
wolf4ood and paullatzelsperger authored Aug 8, 2024
1 parent a2c1778 commit 7327e64
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 10 deletions.
97 changes: 87 additions & 10 deletions developer/wip/for-contributors/contributor-handbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
* [Pre- and Post-Evaluators](#pre--and-post-evaluators)
* [Dynamic functions](#dynamic-functions)
* [2.1.3 Contract definitions](#213-contract-definitions)
* [2.1.4 Contract agreements](#214-contract-agreements)
* [2.1.5 Catalog](#215-catalog)
* [2.1.6 Querying with `QuerySpec` and `Criterion`](#216-querying-with-queryspec-and-criterion)
* [2.1.4 Contract negotiations](#214-contract-negotiations)
* [2.1.5 Contract agreements](#215-contract-agreements)
* [2.1.6 Catalog](#216-catalog)
* [2.1.7 Transfer processes](#217-transfer-processes)
* [2.1.8 Querying with `QuerySpec` and `Criterion`](#218-querying-with-queryspec-and-criterion)
* [2.2 Programming Primitives](#22-programming-primitives)
* [2.2.1 State machines](#221-state-machines)
* [2.2.1.1 Batch-size, sorting and tick-over timeout](#2211-batch-size-sorting-and-tick-over-timeout)
Expand Down Expand Up @@ -59,8 +61,9 @@
* [4.1 Writing Unit-, Component-, Integration-, Api-, EndToEnd-Tests](#41-writing-unit--component--integration--api--endtoend-tests)
* [4.1 Other best practices](#41-other-best-practices)
* [5. Further concepts](#5-further-concepts)
* [4.3 Autodoc](#43-autodoc)
* [4.4 Adapting the Gradle build](#44-adapting-the-gradle-build)
* [5.1 Events and callbacks](#51-events-and-callbacks)
* [5.2 Autodoc](#52-autodoc)
* [5.3 Adapting the Gradle build](#53-adapting-the-gradle-build)
<!-- TOC -->

## 0. Intended audience
Expand Down Expand Up @@ -585,7 +588,77 @@ The sample expresses that a set of assets identified by their ID be made availab

> Note that asset selector expressions are always logically conjoined using an "AND" operation.
#### 2.1.4 Contract agreements
#### 2.1.4 Contract negotiations

If a connector fulfills the [contract policy](#213-contract-definitions), it may initiate the negotiation of a contract for
a particular asset. During that negotiation, both parties can send offers and counter-offers that can contain altered
terms (= policy) as any human would in a negotiation, and the counter-party may accept or reject them.

Contract negotiations have a few key aspects:

- they target _one_ asset
- they take place between a _provider_ and a _consumer_ connector
- they cannot be changed by the user directly
- users can only decline, terminate or cancel them

As a side note it is also important to note that contract offers are _ephemeral_ objects as they are generated
on-the-fly for a particular participant, and they are never persisted in a database and thus cannot be queried through
any API.

Contract negotiations are asynchronous in nature. That means after initiating them, they become (potentially
long-running) stateful processes that are advanced by an internal [state machine](#221-state-machines).
The current state of the negotiation can be queried and altered through the management API.

Here's a diagram of the state machine applied to contract negotiations:

![Contract Negotiation State Machine](diagrams/contract-negotiation-states.png)

A contract negotiation can be initiated from the consumer side by sending a `ContractRequest` to the connector management API.


```json
{
"@context": {
"@vocab": "https://w3id.org/edc/v0.0.1/ns/"
},
"@type": "ContractRequest",
"counterPartyAddress": "http://provider-address",
"protocol": "dataspace-protocol-http",
"policy": {
"@context": "http://www.w3.org/ns/odrl.jsonld",
"@type": "odrl:Offer",
"@id": "offer-id",
"assigner": "providerId",
"permission": [],
"prohibition": [],
"obligation": [],
"target": "assetId"
},
"callbackAddresses": [
{
"transactional": false,
"uri": "http://callback/url",
"events": [
"contract.negotiation"
],
"authKey": "auth-key",
"authCodeId": "auth-code-id"
}
]
}
```
The `counterPartyAddress` is the address where to send the `ContractRequestMessage` via the specified `protocol` (currently [`dataspace-protocol-http`](#27-protocol-extensions-dsp))

The `policy` should hold the same policy associated to the data offering chosen from the [catalog](#216-catalog), plus two additional properties:

- `assigner` the providers `participantId`
- `target` the asset (dataset) ID

In addition, the (optional) `callbackAddresses` array can be used to get notified about state changes of the negotiation. Read more on callbacks in the section about [events and callbacks](#51-events-and-callbacks).

> Note: if the `policy` sent by the consumer differs from the one expressed by the provider, the contract negotiation will fail and transition to a `TERMINATED` state.
#### 2.1.5 Contract agreements

Once a contract negotiation is successfully concluded (i.e. it reaches the `FINALIZED` state), it "turns into" a
contract agreement. It is always the provider connector that gives the final approval. Contract agreements are
Expand All @@ -604,7 +677,7 @@ physical paper contract. Cancelling or terminating a contract is therefor handle
systems. The semantics of cancelling a contract are highly individual to each dataspace and may even bring legal side
effects, so EDC cannot make an assumption here.

#### 2.1.5 Catalog
#### 2.1.6 Catalog

The catalog contains the "data offerings" of a connector and one or multiple service endpoints to initiate a negotiation
for those offerings.
Expand Down Expand Up @@ -719,7 +792,9 @@ available. It uses the [Dataplane Signaling Protocol](#29-data-plane-signaling)

> For details about the FederatedCatalog, please refer to its [documentation](https://github.com/eclipse-edc/FederatedCatalog/).
#### 2.1.6 Querying with `QuerySpec` and `Criterion`
#### 2.1.7 Transfer processes

#### 2.1.8 Querying with `QuerySpec` and `Criterion`

Most of the entities can be queried with the `QuerySpec` object, which is a generic way of expressing limit, offset, sort and filters when querying a collection of objects managed by the EDC stores.

Expand Down Expand Up @@ -1163,6 +1238,8 @@ test pyramid...

## 5. Further concepts

### 4.3 Autodoc
### 5.1 Events and callbacks

### 5.2 Autodoc

### 4.4 Adapting the Gradle build
### 5.3 Adapting the Gradle build
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
'
' Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
'
' This program and the accompanying materials are made available under the
' terms of the Apache License, Version 2.0 which is available at
' https://www.apache.org/licenses/LICENSE-2.0
'
' SPDX-License-Identifier: Apache-2.0
'
' Contributors:
' Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - Initial Draft
'
'

@startuml

state Consumer {
state "INITIAL" as INITIAL_consumer {
}
state "REQUESTING" as REQUESTING_consumer {
}
state "REQUESTED" as REQUESTED_consumer {
}
state "OFFERED" as OFFERED_consumer {
}
state "ACCEPTING" as ACCEPTING_consumer {
}
state "ACCEPTED" as ACCEPTED_consumer {
}
state "AGREED" as AGREED_consumer {
}
state "VERIFYING" as VERIFYING_consumer {
}
state "VERIFIED" as VERIFIED_consumer {
}
state "FINALIZED" as FINALIZED_consumer {
}
state "TERMINATING" as TERMINATING_consumer {
}
state "TERMINATED" as TERMINATED_consumer {
}

[*] --> INITIAL_consumer
INITIAL_consumer --> REQUESTING_consumer
REQUESTING_consumer --> REQUESTED_consumer
REQUESTING_consumer -[dashed]-> REQUESTED_provider : sends\n**ContractRequestMessage**

REQUESTED_consumer -[hidden]-> OFFERED_consumer : used for layout

OFFERED_consumer --> ACCEPTING_consumer
OFFERED_consumer --> REQUESTING_consumer : counter offer
ACCEPTING_consumer --> ACCEPTED_consumer
ACCEPTING_consumer -[dashed]-> ACCEPTED_provider : sends\n**ContractNegotiationEventMessage**

ACCEPTED_consumer -[hidden]-> VERIFYING_consumer : used for layout
AGREED_consumer --> VERIFYING_consumer
VERIFYING_consumer --> VERIFIED_consumer
VERIFYING_consumer -[dashed]-> VERIFIED_provider : sends\n**ContractAgreementVerificationMessage**

VERIFIED_consumer -[hidden]-> FINALIZED_consumer : used for layout

VERIFIED_consumer -[hidden]-> TERMINATING_consumer : used for layout
TERMINATING_consumer -[dashed]-> TERMINATED_provider : sends\n**TransferTerminationMessage**\nmessage
TERMINATING_consumer --> TERMINATED_consumer
}

state Provider {
state "INITIAL" as INITIAL_provider {
}
state "REQUESTED" as REQUESTED_provider {
}
state "OFFERING" as OFFERING_provider {
}
state "OFFERED" as OFFERED_provider {
}
state "AGREEING" as AGREEING_provider {
}
state "AGREED" as AGREED_provider {
}
state "ACCEPTED" as ACCEPTED_provider {
}
state "VERIFIED" as VERIFIED_provider {
}
state "FINALIZING" as FINALIZING_provider {
}
state "FINALIZED" as FINALIZED_provider {
}
state "TERMINATING" as TERMINATING_provider {
}
state "TERMINATED" as TERMINATED_provider {
}

[*] --> INITIAL_provider
INITIAL_provider --> OFFERING_provider
OFFERING_provider --> OFFERED_provider
OFFERING_provider -[dashed]-> OFFERED_consumer : sends\n**ContractOfferMessage**
REQUESTED_provider --> AGREEING_provider
REQUESTED_provider --> OFFERING_provider : counter offer
AGREEING_provider --> AGREED_provider
AGREEING_provider -[dashed]-> AGREED_consumer : sends\n**ContractAgreementMessage**

OFFERED_provider -[hidden]-> REQUESTED_provider : used for layout
AGREED_provider -[hidden]-> VERIFIED_provider : used for layout
REQUESTED_provider -[hidden]-> ACCEPTED_provider : used for layout

ACCEPTED_provider --> AGREEING_provider
VERIFIED_provider --> FINALIZING_provider
FINALIZING_provider --> FINALIZED_provider
FINALIZING_provider -[dashed]-> FINALIZED_consumer : sends\n**ContractNegotiationEventMessage**

FINALIZING_provider -[hidden]-> TERMINATING_provider : used for layout
TERMINATING_provider -[dashed]-> TERMINATED_consumer : sends\n**TransferTerminationMessage**\nmessage
TERMINATING_provider --> TERMINATED_provider
}


@enduml

0 comments on commit 7327e64

Please sign in to comment.