Skip to content

Commit

Permalink
Update SDK to Connector V5 (#4)
Browse files Browse the repository at this point in the history
* Migrate DNA Enmeshed SDK changes to the new repository

* Update code related to the PR comments

* Remove "Accept: application/json" from the header

* Update models

* Fix compilation issues

* Fix typo in the model name

* Update classes and tests according to the PR comments

* Create PeerDeletionInfo class

* Remove RelationshipChange from RequestSourceType

* Update readme

* Update README_dev.md

Co-authored-by: Julian König <[email protected]>

* Update Changelog

* Change WebhookTriggerNames property

* Remove RelationshipAttribute and change successorContent to attribute

* Resolve issues with mustBeAccepted field

* Check active relation status

* Rename PeerDeletionStatus

---------

Co-authored-by: Max Baboshin <[email protected]>
Co-authored-by: Julian König <[email protected]>
  • Loading branch information
3 people authored Sep 13, 2024
1 parent 659f7b1 commit faf95be
Show file tree
Hide file tree
Showing 29 changed files with 396 additions and 513 deletions.
4 changes: 3 additions & 1 deletion README_dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Workflow:
- The Service checks whether there is an inbound request from the connecting peer
- It will return `null` if no request was made by the peer
- It will accept the inbound request if there is any
- It will return the shared attributes, the EnmeshedAddress, the RelationshipChangeId and the RelationShipId on
- It will return the shared attributes, the EnmeshedAddress, the RelationshipId and the RelationshipCreationContent on
success
- Connection between Connector and Enmeshed Wallet app is now set up.

Expand Down Expand Up @@ -235,3 +235,5 @@ record AuthenticationStatus(
- add expired flag to AuthenticationStatus
- 0.6.0
- add possibility to attach Metadata to Authentication-Requests
- 1.0.0
- update SDK to Connector V5
77 changes: 20 additions & 57 deletions src/main/java/eu/enmeshed/EnmeshedOnboardingService.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package eu.enmeshed;

import static java.util.List.of;
import static java.util.Objects.isNull;

import eu.enmeshed.client.EnmeshedClient;
import eu.enmeshed.model.AttributeWrapper;
import eu.enmeshed.model.ContentWrapper;
Expand All @@ -16,9 +13,8 @@
import eu.enmeshed.model.relationshipTemplates.RelationshipTemplateContent;
import eu.enmeshed.model.relationshipTemplates.RelationshipTemplateCreation;
import eu.enmeshed.model.relationships.Relationship;
import eu.enmeshed.model.relationships.RelationshipChange;
import eu.enmeshed.model.relationships.RelationshipChangeRequestContent;
import eu.enmeshed.model.relationships.RelationshipCreationChangeRequestContent;
import eu.enmeshed.model.relationships.RelationshipCreationContent;
import eu.enmeshed.model.relationships.RelationshipStatus;
import eu.enmeshed.model.requestItems.CreateAttributeRequestItem;
import eu.enmeshed.model.requestItems.ReadAttributeRequestItem;
import eu.enmeshed.model.requestItems.RequestItem;
Expand All @@ -33,18 +29,17 @@
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class EnmeshedOnboardingService {

private static final Long QR_CODE_VALIDITY_MINUTES_DEFAULT = 60L;
private static final Integer QR_CODE_NUMBER_OF_ALLOCATIONS = 1;

Expand All @@ -65,11 +60,10 @@ public EnmeshedOnboardingService(
String connectorDisplayName,
List<Class<? extends AttributeValue>> requiredAttributes,
List<Class<? extends AttributeValue>> optionalAttributes) {

this.enmeshedClient = enmeshedClient;
this.requiredAttributes = requiredAttributes;
this.optionalAttributes = optionalAttributes;
this.createAttributes = of();
this.createAttributes = List.of();

// Get IdentifyInfo
identityInfo = enmeshedClient.getIdentityInfo().getResult();
Expand All @@ -84,7 +78,6 @@ public EnmeshedOnboardingService(
List<Class<? extends AttributeValue>> requiredAttributes,
List<Class<? extends AttributeValue>> optionalAttributes,
List<Class<? extends RequestItem>> createAttributes) {

this.enmeshedClient = enmeshedClient;
this.requiredAttributes = requiredAttributes;
this.optionalAttributes = optionalAttributes;
Expand All @@ -98,13 +91,8 @@ public EnmeshedOnboardingService(
}

private AttributeWrapper setupConnectorDisplayName(String connectorDisplayName) {

ResultWrapper<List<AttributeWrapper>> foundAttributes =
enmeshedClient.searchAttributes(
IdentityAttribute.class.getSimpleName(),
identityInfo.getAddress(),
DisplayName.class.getSimpleName());

enmeshedClient.searchAttributes(DisplayName.class.getSimpleName());
Optional<AttributeWrapper> displayNameAttribute =
foundAttributes.getResult().stream()
.filter(attribute -> attribute.getContent().getValue() instanceof DisplayName)
Expand All @@ -130,7 +118,6 @@ private AttributeWrapper setupConnectorDisplayName(String connectorDisplayName)

// Attribute not found - Create it!
IdentityAttribute identityAttribute = new IdentityAttribute();
identityAttribute.setOwner(identityInfo.getAddress());
identityAttribute.setValue(DisplayName.builder().value(connectorDisplayName).build());

AttributeWrapper createdDisplayNameAttribute =
Expand All @@ -152,14 +139,12 @@ public RegistrationData generateQrCodeForRegistrationAsJpg(
String displayTextSharedAttributes,
String displayTextCreateAttributes,
Long qrCodeValidityMinutes) {

RelationshipTemplate relationshipTemplate =
createOnboardingRelationshipTemplate(
displayTextRequestedAttributes,
displayTextSharedAttributes,
displayTextCreateAttributes,
qrCodeValidityMinutes);

Response qrCodeResponse =
enmeshedClient.getQrCodeForRelationshipTemplate(relationshipTemplate.getId());

Expand Down Expand Up @@ -216,56 +201,36 @@ public RegistrationResult checkRegistrationState(
}

Relationship relationship = relationships.get(0);
RelationshipChange relationshipChange = relationship.getChanges().get(0);

RelationshipChangeRequestContent relationshipChangeRequestContent =
relationshipChange.getRequest().getContent();

RelationshipCreationChangeRequestContent relationshipCreationChangeRequestContent =
(RelationshipCreationChangeRequestContent) relationshipChangeRequestContent;

RelationshipCreationContent creationContent = relationship.getCreationContent();
Map<Class<? extends AttributeValue>, AttributeValue> attributes =
getSharedSimpleAttributesFromResponseItems(
relationshipCreationChangeRequestContent.getResponse().getItems());
getSharedSimpleAttributesFromResponseItems(creationContent.getResponse().getItems());

if (relationshipChange.getStatus() == RelationshipChange.Status.PENDING) {
RelationshipStatus status = relationship.getStatus();
if (status == RelationshipStatus.PENDING) {
boolean decision = acceptanceDecider.test(attributes);

if (decision) {
enmeshedClient.acceptRelationshipChange(
relationship.getId(),
relationshipChange.getId(),
ContentWrapper.containing(Collections.emptyMap()));
enmeshedClient.acceptRelationship(relationship.getId());
} else {
enmeshedClient.rejectRelationshipChange(
relationship.getId(),
relationshipChange.getId(),
ContentWrapper.containing(Collections.emptyMap()));
enmeshedClient.rejectRelationship(relationship.getId());
}

return checkRegistrationState(relationshipTemplateId, registrationResult -> decision);
} else if (relationshipChange.getStatus() == RelationshipChange.Status.ACCEPTED) {

} else if (status == RelationshipStatus.ACTIVE) {
// Request was accepted by User and us - Get the send Attributes and return them
return new RegistrationResult(
attributes,
relationships.get(0).getPeerIdentity().getAddress(),
relationshipChange.getId(),
relationship.getId(),
true);

} else if (relationshipChange.getStatus() == RelationshipChange.Status.REJECTED) {

} else if (status == RelationshipStatus.REJECTED) {
// Request was accepted by User and us - Get the send Attributes and return them
return new RegistrationResult(
attributes,
relationships.get(0).getPeerIdentity().getAddress(),
relationshipChange.getId(),
relationship.getId(),
false);
} else {

// Unknown Relationship State - This shouldn't happen.
return null;
}
}
Expand Down Expand Up @@ -309,15 +274,12 @@ private RelationshipTemplate createOnboardingRelationshipTemplate(
RequestItemGroup sharedAttributesGroup =
RequestItemGroup.builder()
.title(displayTextSharedAttributes)
.mustBeAccepted(true)
.items(of(ShareAttributeRequestItem.fromWrapper(connectorDisplayNameAttribute, true)))
.items(
List.of(ShareAttributeRequestItem.fromWrapper(connectorDisplayNameAttribute, true)))
.build();

RequestItemGroup requestedAttributesGroup =
RequestItemGroup.builder()
.title(displayTextRequestedAttributes)
.mustBeAccepted(true)
.build();
RequestItemGroup.builder().title(displayTextRequestedAttributes).build();

List<RequestItem> readAttributeItems = new ArrayList<>();
requiredAttributes.stream()
Expand All @@ -329,7 +291,7 @@ private RelationshipTemplate createOnboardingRelationshipTemplate(
requestedAttributesGroup.setItems(readAttributeItems);

RequestItemGroup createAttributeGroup =
RequestItemGroup.builder().title(displayTextCreateAttributes).mustBeAccepted(true).build();
RequestItemGroup.builder().title(displayTextCreateAttributes).build();
List<RequestItem> createAttributeItems = new ArrayList<>();
createAttributes.stream()
.map(
Expand All @@ -351,7 +313,9 @@ private RelationshipTemplate createOnboardingRelationshipTemplate(
.build();

Long qrCodeValidityTime =
isNull(qrCodeValidityMinutes) ? QR_CODE_VALIDITY_MINUTES_DEFAULT : qrCodeValidityMinutes;
Objects.isNull(qrCodeValidityMinutes)
? QR_CODE_VALIDITY_MINUTES_DEFAULT
: qrCodeValidityMinutes;

RelationshipTemplateCreation relationShipTemplateCreation =
RelationshipTemplateCreation.builder()
Expand All @@ -369,7 +333,6 @@ public record RegistrationData(
public record RegistrationResult(
Map<Class<? extends AttributeValue>, AttributeValue> attributes,
String enmeshedAddress,
String relationshipChangeId,
String relationshipId,
boolean accepted) {}
}
35 changes: 15 additions & 20 deletions src/main/java/eu/enmeshed/client/EnmeshedClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import java.util.List;

public interface EnmeshedClient {

ObjectMapper objectMapper =
new ObjectMapper()
.registerModule(new JavaTimeModule())
Expand All @@ -47,13 +46,11 @@ public interface EnmeshedClient {
.setDateFormat(new StdDateFormat().withColonInTimeZone(true));

static EnmeshedClient configure(String url, String apiKey) {

return configure(url, apiKey, new Request.Options(), Logger.Level.NONE);
}

static EnmeshedClient configure(
String url, String apiKey, Request.Options options, Logger.Level loggerLevel) {

return Feign.builder()
.decoder(new JacksonDecoder(objectMapper))
.encoder(new FormEncoder(new JacksonEncoder(objectMapper)))
Expand All @@ -77,16 +74,17 @@ static EnmeshedClient configure(
/*
Attributes
*/
@RequestLine("GET /api/v2/Attributes?content.@type={0}&content.owner={1}&content.value.@type={2}")
ResultWrapper<List<AttributeWrapper>> searchAttributes(
@Param("0") String contentType,
@Param("1") String contentOwner,
@Param("2") String contentValueType);
@RequestLine("GET /api/v2/Attributes?content.value.@type={type}")
ResultWrapper<List<AttributeWrapper>> searchAttributes(@Param("type") String contentValueType);

@RequestLine("POST /api/v2/Attributes")
@Headers("Content-Type: application/json")
@Headers({"Content-Type: application/json"})
ResultWrapper<AttributeWrapper> createAttribute(ContentWrapper<Attribute> attribute);

@RequestLine("GET /api/v2/Attributes/{id}")
@Headers("Content-Type: application/json")
ResultWrapper<AttributeWrapper> getAttributeById(@Param("id") String attributeId);

/*
Relationship Templates
*/
Expand All @@ -111,19 +109,16 @@ ResultWrapper<QrCode> createRelationshipQrCode(
ResultWrapper<List<Relationship>> searchRelationships(
@Param("0") String templateId, @Param("1") String peer, @Param("2") String status);

@RequestLine("PUT /api/v2/Relationships/{0}/Changes/{1}/Accept")
@RequestLine("GET /api/v2/Relationships/{id}")
ResultWrapper<Relationship> getRelationshipById(@Param("id") String id);

@RequestLine("PUT /api/v2/Relationships/{id}/Accept")
@Headers("Content-Type: application/json")
ResultWrapper<Relationship> acceptRelationshipChange(
@Param("0") String relationshipId,
@Param("1") String changeId,
ContentWrapper<Object> dummyBody);
ResultWrapper<Relationship> acceptRelationship(@Param("id") String id);

@RequestLine("PUT /api/v2/Relationships/{0}/Changes/{1}/Reject")
@RequestLine("PUT /api/v2/Relationships/{0}/Reject")
@Headers("Content-Type: application/json")
ResultWrapper<Relationship> rejectRelationshipChange(
@Param("0") String relationshipId,
@Param("1") String changeId,
ContentWrapper<Object> dummyBody);
ResultWrapper<Relationship> rejectRelationship(@Param("id") String id);

/*
Messages
Expand Down Expand Up @@ -165,7 +160,7 @@ ResultWrapper<LocalRequest> acceptIncomingRequestById(
*/
@Retryable
@RequestLine("POST /api/v2/Files/Own")
@Headers({"Content-Type: multipart/form-data", "accept: application/json"})
@Headers({"Content-Type: multipart/form-data"})
ResultWrapper<FileMetaData> uploadNewOwnFile(FileUploadRequest fileUploadRequest);

@Retryable
Expand Down
6 changes: 1 addition & 5 deletions src/main/java/eu/enmeshed/model/AttributeWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@
@Setter
@SuperBuilder
public class AttributeWrapper extends ContentWrapper<Attribute> {

private String id;

private ZonedDateTime createdAt;

private AttributeShareInfo shareInfo;

private String succeededBy;

private String succeeds;
private Boolean isDefault;
}
13 changes: 8 additions & 5 deletions src/main/java/eu/enmeshed/model/attributes/Attribute.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package eu.enmeshed.model.attributes;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import eu.enmeshed.model.attributes.values.AttributeValue;
Expand All @@ -21,15 +24,15 @@
@Getter
@Setter
@SuperBuilder
public abstract class Attribute {
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Attribute {
@JsonProperty("@type")
private String type;

private String owner;

private List<String> tags;

private ZonedDateTime validFrom;

private ZonedDateTime validTo;

private AttributeValue value;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
@Setter
@SuperBuilder
public abstract class SimpleStringAttributeValue extends AttributeValue {

private String value;

@Override
public String toString() {
return getValue();
}
}
2 changes: 1 addition & 1 deletion src/main/java/eu/enmeshed/model/event/Webhook.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class Webhook<T extends WebhookData> {
WebhookTriggerNames.Consumption.OUTGOING_REQUEST_CREATED,
WebhookTriggerNames.Consumption.OUTGOING_REQUEST_CREATED_AND_COMPLETED,
WebhookTriggerNames.Consumption
.OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CHANGE_CREATED_AND_COMPLETED
.OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CREATED_AND_COMPLETED
}),
@JsonSubTypes.Type(
value = LocalAttribute.class,
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/eu/enmeshed/model/event/WebhookTrigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public enum WebhookTrigger {

@JsonProperty(
WebhookTriggerNames.Consumption
.OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CHANGE_CREATED_AND_COMPLETED)
CONSUMPTION__OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CHANGE_CREATED_AND_COMPLETED,
.OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CREATED_AND_COMPLETED)
CONSUMPTION__OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CREATED_AND_COMPLETED,

@JsonProperty(WebhookTriggerNames.Consumption.OUTGOING_REQUEST_STATUS_CHANGED)
CONSUMPTION__OUTGOING_REQUEST_STATUS_CHANGED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ public abstract static class Consumption {
public static final String OUTGOING_REQUEST_CREATED = "consumption.outgoingRequestCreated";
public static final String OUTGOING_REQUEST_CREATED_AND_COMPLETED =
"consumption.outgoingRequestCreatedAndCompleted";
public static final String
OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CHANGE_CREATED_AND_COMPLETED =
"consumption.outgoingRequestFromRelationshipCreationChangeCreatedAndCompleted";
public static final String OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CREATED_AND_COMPLETED =
"consumption.outgoingRequestFromRelationshipCreationCreatedAndCompleted";
public static final String OUTGOING_REQUEST_STATUS_CHANGED =
"consumption.outgoingRequestStatusChanged";
public static final String RELATIONSHIP_TEMPLATE_PROCESSED =
Expand Down
Loading

0 comments on commit faf95be

Please sign in to comment.