The Runtime of enmeshed has recently been updated from version 4 to version 5. Accordingly, a new version of the Connector has also been released to make the updated Runtime available to Integrators of Connectors. The version update has resulted in some breaking changes. To support the migration of existing systems to the new version, the breaking changes made are listed and explained in this migration guide.

Step-by-Step Instructions

The step-by-step instructions can be consulted to start the migration to version 5 directly. More detailed explanations can be found below.

Connector Setup

  • The data from the database that was used by the Connector of the former version is outdated. This is because the format of addresses has changed to DIDs, for example. For this reason, the old data must be deleted. Alternatively, the database can be deleted as a whole and set up again.
  • The image used to run the Connector must be updated to version 5.
  • Some changes must be made to the configuration of the Connector.
    • It must be ensured that a Backbone is used which is compatible with version 5 of the Connector. This means that a Backbone of version 6 must be used. Therefore, specify appropriate Backbone credentials in the fields transportLibrary.baseUrl, transportLibrary.platformClientId and transportLibrary.platformClientSecret of the configuration. The URL <baseUrl of Backbone>/api/v1/version can be accessed to validate the version of the Backbone.
    • The AutoAcceptRelationshipCreationChangesModule has been renamed to the AutoAcceptPendingRelationshipsModule, because the RelationshipChanges have been removed. For this reason, the modules.autoAcceptRelationshipCreationChanges field must be renamed to modules.autoAcceptPendingRelationships in the configuration if it was previously specified. In addition, it must be made sure that the modules.autoAcceptRelationshipCreationChanges.responseContent field is removed.
    • In version 4, the WebhooksV2Module module has already been renamed to the WebhooksModule. However, backwards compatibility was ensured. With the migration to version 5, the modules.webhooksV2 field must be renamed to modules.webhooks in the configuration if it was previously specified and the migration to the WebhooksModule has not yet taken place.

Removed and Changed Data Structures

Changed Behavior of Known Features

Changes to Error Codes, Connector Routes and Events

Changes have been made to the error codes, use cases and events. Naturally, the Connector routes associated with the changed use cases of the Runtime are often affected as well. All these changes may lead to unexpected behavior when updating from version 4 to version 5. In this case, it is worth taking a look at the following lists:

Detailed Explanations

The aspects to be taken into account when migrating to version 5, which were briefly described in the step-by-step instructions, are explained in more detail in the following.

DIDs as Addresses

Each Identity within enmeshed has a unique address for identification. The format of this address has changed from <3-character realm><32- or 33-character base58-encoded string> to did:e:<hostname of Backbone>:dids:<22-character lowercase hexadecimal string>. Accordingly, the realm property of the Identity was removed as well. Furthermore, the two error codes error.runtime.MultiAccount.WrongRealm and error.transport.identity.realmLength have been removed.

Removal of RelationshipChanges

Previously, the history of changes made to a Relationship was stored in its changes property. The type of this property was given by an array of RelationshipChanges. Due to the inconvenience of providing new features for the management of Relationships using RelationshipChanges, the RelationshipChanges have now been removed. Consequently, the changes property of the Relationship was also removed. Instead, there is now a new auditLog property in which the history of changes made to a Relationship is stored. In order to typify the Relationship’s auditLog, the new data object type RelationshipAuditLogEntry was defined. An overview of the modifications to the data object type Relationship, which were caused by the removal of the RelationshipChanges, can be found below.

In contrast to the new RelationshipAuditLogEntries, the former RelationshipChanges were not only used to store changes made to a Relationship, but also to perform operations on a Relationship. For example, there was the RelationshipChange with "Creation" as type, which stored the content required for the initial creation of a pending Relationship within its request property. To activate this pending Relationship, the other Identity involved in the Relationship had to accept the RelationshipChange. Alternatively, it could decide not to establish the Relationship by rejecting the RelationshipChange. The two use cases of accepting and rejecting RelationshipChanges have been removed. Instead, the content required to initially create a pending Relationship is now stored in the newly introduced creationContent property of the Relationship itself. It fulfills the same role as the previous request.content property of the RelationshipChange with the difference that it now has the type RelationshipCreationContent instead of RelationshipCreationChangeRequestContent if a RelationshipTemplate whose content is of the type RelationshipTemplateContent was used for the initial creation of the pending Relationship. Otherwise, the type of the creationContent property of the Relationship is ArbitraryRelationshipCreationContent. Before the introduction of the new mandatory wrappers for non-standard content, such arbitrary creationContent of the Relationship was stored in the request.content property of the RelationshipChange by also permitting the storage of data of unknown type.

The functionalities of the old two use cases of accepting and rejecting RelationshipChanges are now provided by the two new use cases Accept Relationship and Reject Relationship. Accordingly, the Connector routes using RelationshipChanges were replaced. When using the two new Connector routes, which work directly on the Relationships, a request body no longer needs to be provided. This means that no content must be sent with any of these operations anymore. The former, more generic Connector routes using RelationshipChanges could also have been used to accept or reject changes to a Relationship other than the establishment of an active Relationship, which might have required the transmission of additional data.

Old Connector route New Connector route
PUT /api/v2/Relationships/{relationshipId}/Changes/{changeId}/Accept (with body) PUT /api/v2/Relationships/{relationshipId}/Accept (no body)
PUT /api/v2/Relationships/{relationshipId}/Changes/{changeId}/Reject (with body) PUT /api/v2/Relationships/{relationshipId}/Reject (no body)

Modifications to Relationship

A Relationship is returned by various Connector routes and events. The data object type Relationship has been modified as follows due to the removal of the RelationshipChanges:

Name Type Changes
status "Pending" | "Active" | "Rejected" | "Revoked" |"Terminated" | "DeletionProposed" The type of the status property has been changed. The two statuses "Terminated" and "DeletionProposed" have been added because of the termination of Relationships.
  • Terminated: this means that the Relationship has been terminated.
  • DeletionProposed: this means that one part of the Relationship wants to terminate the Relationship.
changes RelationshipChange[] The changes property has been removed. The history of changes made to this Relationship is now recorded in the new auditLog property.
creationContent RelationshipCreationContent | ArbitraryRelationshipCreationContent The creationContent property has been added. More information on the type of the creationContent property can be found in the section on new mandatory wrappers.
auditLog RelationshipAuditLogEntry[] The auditLog property has been added. It stores the history of changes made to this Relationship, which was recorded in the former changes property. In order to typify the Relationship’s auditLog, the new data object type RelationshipAuditLogEntry was defined.

Definition of RelationshipAuditLogEntry

The data object type RelationshipAuditLogEntry was defined, which typifies the new auditLog property of the Relationship. For example, the first RelationshipAuditLogEntry of the auditLog of a Relationship has "Creation" as reason, no oldStatus and "Pending" as newStatus and is created by the Identity that has created the Relationship.

New Mandatory Wrappers for Non-Standard Content of Messages, RelationshipTemplates and Relationships

New wrapping types have been introduced for sending arbitrary content that does not fit the standard content types of enmeshed, the ArbitraryMessageContent for Messages with non-standard content, the ArbitraryRelationshipTemplateContent for RelationshipTemplates with non-standard content and the ArbitraryRelationshipCreationContent for Relationships with non-standard creationContent. Please note that the creationContent of the Relationship itself is newly introduced in the section about the Removal of RelationshipChanges. These new wrappers are all of the following form, whereby the <...> notation indicates a placeholder for one of the transport types Message, RelationshipTemplate or Relationship:

{
  "@type": "Arbitrary<...>Content",
  "value": any,
}

Thus, when sending a Message with non-standard content via POST /api/v2/Messages, instead of using the parameter content : <arbitrary content of Message>, it must be used:

"content": {
  "@type": "ArbitraryMessageContent",
  "value": <arbitrary content of Message>
}

Similarly, when creating an own RelationshipTemplate with non-standard content via the Connector route POST /api/v2/RelationshipTemplates/Own, it must be provided:

"content": {
  "@type": "ArbitraryRelationshipTemplateContent",
  "value": <arbitrary content of RelationshipTemplate>
}

Last but not least, when creating a Relationship with non-standard creationContent via the Connector route POST /api/v2/Relationships, it must be utilized:

"creationContent": {
  "@type": "ArbitraryRelationshipCreationContent",
  "value": <arbitrary content for creation of Relationship>
}

When reading the value from a Message or a RelationshipTemplate with non-standard content, the relevant property is thus changed from content to content.value. Similarly, when reading the value of a Relationship with non-standard creationContent, attention must be paid to the creationContent.value property.

Removal of the mustBeAccepted Property of the RequestItemGroup

A RequestItemGroup still provides a way of grouping the RequestItems contained in its items property in the UI. However, the mustBeAccepted property of the RequestItemGroup has now been removed, as it had easily misunderstood interactions with the mustBeAccepted property of the RequestItems. More precisely, a certain, complicated dependency of the acceptance of the RequestItems contained in its items property could be described via the mustBeAccepted property of the RequestItemGroup:

  • If the value of the mustBeAccepted property of the RequestItemGroup was set to true, all RequestItems contained within its items property whose value of their respective mustBeAccepted property is true must be accepted if the entire Request is accepted. Included RequestItems whose value of their respective mustBeAccepted property is false could still be rejected.
  • If the value of the mustBeAccepted property of the RequestItemGroup was set to false, all RequestItems contained in its items property could be rejected if the entire Request is accepted. However, if any RequestItem contained was to be accepted, all RequestItems whose mustBeAccepted property is true must also be accepted when the Request is accepted. In this respect, there was a dependency between the individual RequestItems.

It was not clear enough from the mustBeAccepted property of the RequestItemGroup which of the RequestItems contained within its items property are optional or mandatory, depending on how their respective values of the mustBeAccepted property are set.

Making it necessary to accept certain RequestItems once certain other RequestItems have been accepted is nevertheless a useful feature that will be provided in the future, but will be implemented without the mustBeAccepted property of the RequestItemGroup.

In addition, in contrast to the RequestItems, a RequestItemGroup did not have to be explicitly accepted or rejected when a Request was accepted, which is why it was confusing that both the RequestItemGroups and the RequestItems had a mustBeAccepted property. Overall, it was therefore decided to remove the mustBeAccepted property of the RequestItemGroup.

The mustBeAccepted property of the RequestItems will be kept.

Furthermore, please note that the removal of this property has resulted in the renaming of the error code error.consumption.requests.decide.validation.itemAcceptedButParentNotAccepted to error.consumption.requests.decide.validation.itemAcceptedButRequestNotAccepted, as listed and explained below in the section on removed and changed error codes.

Changed Type of the owner Property of the ThirdPartyRelationshipAttributeQuery

The ThirdPartyRelationshipAttributeQuery is usually used within the query property of a ReadAttributeRequestItem, which in turn appears in the items property of a Request. It is used to query an existing RelationshipAttribute, which exists within a Relationship between the Recipient of the Request and a third party, as the Sender of the Request. The owner property of the ThirdPartyRelationshipAttributeQuery determines the owner of the queried RelationshipAttribute. Previously, it was possible within the owner property of the ThirdPartyRelationshipAttributeQuery to specify a concrete address for the owner of the queried RelationshipAttribute or an empty string as a placeholder for the address of the Recipient of the Request instead. Thus, a RelationshipAttribute could be queried which is owned by a specific third party or which is owned by the Recipient of the Request itself.

However, it was not possible to query a RelationshipAttribute that is owned by any of the third parties specified within the thirdParty property of the ThirdPartyRelationshipAttributeQuery. It was also not possible to query a RelationshipAttribute that could be owned by either one of the specified third parties or the Recipient of the Request. The type of the owner property of the ThirdPartyRelationshipAttributeQuery has therefore been changed to extend the functionalities. The values "", "recipient" or "thirdParty" can now be specified for this owner property. Specify the string "recipient" if the Recipient should be the owner of the queried RelationshipAttribute. Use the string "thirdParty" if any of the third parties specified in the array string thirdParty should be the owner. If both the Recipient and each of the given third parties may be the owner, an empty string "" must be specified. Using this option is useful if the owner of the queried RelationshipAttribute is not known in advance.

This change enables the Sender of the Request to specify more precisely which Identity should be the owner of a RelationshipAttribute when querying it. As a result, real application scenarios can be better represented.

Synchronization With Backbone Returns No Content Anymore

Previously, the synchronization with the Backbone via the route POST /api/v2/Account/Sync returned a list of Relationships and Messages with the HTTP code 201. This has been changed to the sync returning nothing with the HTTP code 204. This removes the support for the workflow of regularly calling the sync and checking the response since unexpected response values happen if syncs are executed from different spots. We recommend working event-based with the Message Broker Publisher Module, which sends events to a message broker you have set up. We send a variety of events like consumption.incomingRequestReceived or consumption.incomingRequestStatusChanged, each of them containing the relevant changed object. See Connector Events for the full list. Slightly related, we also recommend using the recently published Server-Sent Events Module, which listens to events emitted from the Backbone and syncs with the Backbone when an event is received.

Validation of Requests

Validations have been added when sending Requests and responding to Requests to ensure the proper functioning of business processes. However, the added validations can also reduce flexibility in the use of Requests, which is why they could cause previously functioning Request flows to fail. Most affected by the changes are Requests where an Attribute is shared with a peer, an Attribute is proposed to a peer, an Attribute is read from a peer or an Attribute is created for a peer. In the case of problems with previously functioning Request flows that now fail, it is recommended that the corresponding documented scenarios be consulted. Descriptive error messages are also thrown to help restore the integrity of Request flows.

Sending of Requests

Even though reference has already been made to the corresponding scenarios in the documentation, a few examples of the added validation for sending Requests are given in the following.

  • The new error code error.consumption.requests.attributeQueryMismatch has been implemented to mark provided Attributes that do not fulfill a certain AttributeQuery accordingly. It is thrown, for example, if the Sender of the Request, which contains a ProposeAttributeRequestItem within its items property, specifies an attribute and a query that are incompatible.
  • If the Sender of a Request wants to share an IdentityAttribute that is owned by itself with the Recipient of the Request by using a ShareAttributeRequestItem, the Sender must specify its associated RepositoryAttribute in the attribute property of the ShareAttributeRequestItem. It is no longer permitted to specify shared copies, meaning own shared IdentityAttributes, instead.

Responding to Requests

Even though reference has already been made to the corresponding scenarios in the documentation, a few examples of the added validation for responding to Requests are given in the following.

Removed and Changed Error Codes

An overview of the Error codes that may occur is given on the corresponding documentation page. The most important changes regarding the error codes due to the update from version 4 to version 5 are:

Removed, Changed and Added Use Cases

An overview of the Use Cases that may occur is given on the corresponding documentation page. The most important changes regarding the use cases due to the update from version 4 to version 5 are summarized in the following subsections. The effects of these changes on the Connector routes are also described.

Revocation of Relationships

The Revoke Relationship use case has been added. It is now possible to revoke a Relationship with "Pending" as status if it was created by yourself. To execute this use case, the Connector route PUT /api/v2/Relationships/{id}/Revoke can be used.

Removal of RelationshipChanges

The removal of RelationshipChanges is the reason why the following use cases are removed:

  • The use case for accepting RelationshipChanges along with the associated Connector route PUT /api/v2/Relationships/{id}/Changes/{changeId}/Accept.
  • The use case for rejecting RelationshipChanges along with the associated Connector route PUT /api/v2/Relationships/{id}/Changes/{changeId}/Reject.

Therefore, the following new use cases had to be added, which now provide these functionalities:

  • The Accept Relationship use case along with the PUT /api/v2/Relationships/{id}/Accept Connector route.
  • The Reject Relationship use case along with the PUT /api/v2/Relationships/{id}/Reject Connector route.

Termination of Relationships

Based on the restructuring of the Relationship by removing the RelationshipChanges, the new functionality of terminating Relationships was implemented. In connection with this feature, the following use cases have been added, whereby the corresponding added Connector routes can be found on the documentation pages of the respective use cases:

Renaming of the Use Case GetSharedVersionsOfRepositoryAttribute to GetSharedVersionsOfAttribute

Taking ThirdPartyRelationshipAttributes into account, we wanted to extend the functionality of the use case of getting shared versions of a RepositoryAttribute to RelationshipAttributes.

For this reason, the Get shared versions of an Attribute use case was already added in version 4 and the use case of getting shared versions of a RepositoryAttribute was marked as deprecated. It has now been deleted with the update to version 5.

Please note, however, that the Connector route GET /api/v2/Attributes/{id}/Versions/Shared that belonged to the use case of getting shared versions of a RepositoryAttribute can still be used. If the Connector route GET /api/v2/Attributes/{id}/Versions/Shared is executed, the Get shared versions of an Attribute use case is now executed instead. As the functionality has only been extended, there is no breaking change with regard to the Connector route.

Less Input Needed for the Use Case CreateRepositoryAttribute

In version 4, there was already a use case for creating Attributes for yourself that could be executed by Connector route POST /api/v2/Attributes. An Attribute created for yourself is automatically an IdentityAttribute which is owned by yourself. Technically, this corresponds exactly to the creation of a RepositoryAttribute. Therefore, the use case for creating Attributes for yourself is named the Create a RepositoryAttribute use case.

When creating Attributes for yourself, it is therefore apparently not valuable to have to explicitly specify that an IdentityAttribute should be created instead of a RelationshipAttribute and that the IdentityAttribute should be owned by yourself instead of another Identity. For this reason, when executing the Connector route POST /api/v2/Attributes, which corresponds to the execution of the associated Create a RepositoryAttribute use case, less input must now be provided, since the @type and the owner of the Attribute to be created may no longer be specified.

Renamed and Added Events

There are several Connector events which have been added. Regarding the termination of Relationships, for example, the following have been added:

  • transport.relationshipReactivationRequested
  • transport.relationshipReactivationCompleted
  • transport.relationshipDecomposedBySelf

The event consumption.outgoingRequestFromRelationshipCreationChangeCreatedAndCompleted was renamed to consumption.outgoingRequestFromRelationshipCreationCreatedAndCompleted due to the removal of RelationshipChanges.

An overview of the Connector Events that may occur is given on the corresponding documentation page.

Renamed Modules

Some Modules of the Connector have been renamed:

  • The AutoAcceptRelationshipCreationChangesModule has been renamed to the AutoAcceptPendingRelationshipsModule, because the RelationshipChanges have been removed. For this reason, the modules.autoAcceptRelationshipCreationChanges field must be renamed to modules.autoAcceptPendingRelationships in the configuration if it was previously specified. The modules.autoAcceptRelationshipCreationChanges.responseContent field must be removed additionally.
  • The WebhooksV2Module module has already been renamed to the WebhooksModule in version 4. However, backwards compatibility was ensured. With the migration to version 5, the modules.webhooksV2 field must be renamed to modules.webhooks in the configuration if it was previously specified and the migration to the WebhooksModule has not yet taken place.

An overview of the Connector Modules that may occur is given on the corresponding documentation page.