Skip to content

Commit

Permalink
feat(relay): Add global id
Browse files Browse the repository at this point in the history
  • Loading branch information
gfanton committed Sep 11, 2018
1 parent f5ee4f1 commit 6871bc9
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 35 deletions.
102 changes: 88 additions & 14 deletions core/api/node/graphql/converts.go
Expand Up @@ -2,13 +2,64 @@ package graphql

import (
"encoding/base64"
"fmt"
"strings"

"berty.tech/core/api/node/graphql/model"
"berty.tech/core/api/node/graphql/scalar"
"berty.tech/core/api/p2p"
"berty.tech/core/entity"
)

type EntityKind string

var (
ContactKind EntityKind = "CONTACT"
ConversationKind EntityKind = "CONVERSATION"
EventKind EntityKind = "EVENT"
DeviceKind EntityKind = "DEVICE"
ConversationMemberKind EntityKind = "CONVERSATION_MEMBER"
)

var EntityKindMap = map[string]EntityKind{
"CONTACT": ContactKind,
"CONVERSATION": ConversationKind,
"EVENT": EventKind,
"DEVICE": DeviceKind,
"CONVERSATION_MEMBER": ConversationMemberKind,
}

type globalID struct {
Kind EntityKind
ID string
}

func (gid *globalID) String() string {
id := strings.Join([]string{string(gid.Kind), gid.ID}, ":")
return base64.StdEncoding.EncodeToString([]byte(id))

}

func (gid *globalID) FromString(e string) error {
bs, err := base64.StdEncoding.DecodeString(e)
if err != nil {
return err
}

sid := strings.Split(string(bs), ":")
if len(sid) != 2 {
return fmt.Errorf("Not a valid global id, should have two element speared by `:`")
}

if kind, ok := EntityKindMap[sid[0]]; ok {
gid.Kind = kind
gid.ID = sid[1]
return nil
}

return fmt.Errorf("Unknown entity kind `%s`", sid[0])
}

func convertContactStatus(value entity.Contact_Status) *model.BertyEntityContactStatus {
ret, ok := map[entity.Contact_Status]model.BertyEntityContactStatus{
entity.Contact_Unknown: model.BertyEntityContactStatusUnknown,
Expand All @@ -33,8 +84,13 @@ func convertContact(contact *entity.Contact) *model.BertyEntityContact {
return &model.BertyEntityContact{}
}

contactGlobalID := &globalID{
Kind: ContactKind,
ID: contact.ID,
}

return &model.BertyEntityContact{
ID: contact.ID,
ID: contactGlobalID.String(),
Status: convertContactStatus(contact.Status),
DisplayName: &contact.DisplayName,
CreatedAt: &scalar.DateTime{Value: &contact.CreatedAt},
Expand Down Expand Up @@ -64,8 +120,13 @@ func convertConversationMember(conversationMember *entity.ConversationMember) *m
return &model.BertyEntityConversationMember{}
}

conversationMemberGlobalID := &globalID{
Kind: ConversationMemberKind,
ID: conversationMember.ID,
}

return &model.BertyEntityConversationMember{
ID: conversationMember.ID,
ID: conversationMemberGlobalID.String(),
Status: convertConversationMemberStatus(conversationMember.Status),
Contact: convertContact(conversationMember.Contact),
ConversationID: &conversationMember.ConversationID,
Expand All @@ -91,8 +152,13 @@ func convertConversation(conversation *entity.Conversation) *model.BertyEntityCo
members = append(members, convertConversationMember(member))
}

conversationGlobalID := &globalID{
Kind: ConversationKind,
ID: conversation.ID,
}

return &model.BertyEntityConversation{
ID: conversation.ID,
ID: conversationGlobalID.String(),
Title: &conversation.Title,
Topic: &conversation.Topic,
Members: members,
Expand Down Expand Up @@ -123,8 +189,13 @@ func convertEvent(event *p2p.Event) *model.BertyP2pEvent {
return &model.BertyP2pEvent{}
}

eventGlobalID := &globalID{
Kind: EventKind,
ID: event.ID,
}

return &model.BertyP2pEvent{
ID: &event.ID,
ID: eventGlobalID.String(),
SenderID: &event.SenderID,
Direction: convertEventDirection(event.Direction),
SenderAPIVersion: convertUint32(event.SenderAPIVersion),
Expand Down Expand Up @@ -169,7 +240,7 @@ func convertEventKind(value p2p.Kind) *model.BertyP2pKind {
// return nil
// }

// t := value.UTC().Format(time.RFC3339Nano)
// t := value.UTC().Format(time.RFC3339

// return &t
// }
Expand All @@ -189,16 +260,19 @@ func convertEventDirection(value p2p.Event_Direction) *model.BertyP2pEventDirect
return &ret
}

func memberSliceFromContactIds(contactsID []string) []*entity.ConversationMember {
var members []*entity.ConversationMember

for i := range contactsID {
contactID := contactsID[i]
func memberSliceFromContactIds(contactsID []string) ([]*entity.ConversationMember, error) {
members := make([]*entity.ConversationMember, len(contactsID))
for i, cid := range contactsID {
var gid globalID
err := gid.FromString(cid)
if err != nil {
return nil, err
}

members = append(members, &entity.ConversationMember{
ContactID: contactID,
})
members[i] = &entity.ConversationMember{
ContactID: gid.ID,
}
}

return members
return members, nil
}
19 changes: 10 additions & 9 deletions core/api/node/graphql/graph/graph.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/api/node/graphql/model/model.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

78 changes: 70 additions & 8 deletions core/api/node/graphql/resolver.go
Expand Up @@ -46,9 +46,15 @@ func (r *mutationResolver) ContactRequest(ctx context.Context, input model.Conta
input.IntroText = &tmp
}

var contactGlobalID globalID
err := contactGlobalID.FromString(input.ContactID)
if err != nil {
return nil, err
}

req := &service.ContactRequestInput{
Contact: &entity.Contact{
ID: input.ContactID,
ID: contactGlobalID.ID,
},
IntroText: *input.IntroText,
}
Expand All @@ -65,8 +71,14 @@ func (r *mutationResolver) ContactRequest(ctx context.Context, input model.Conta
}

func (r *mutationResolver) ContactRemove(ctx context.Context, input model.ContactRemoveInput) (*model.ContactRemovePayload, error) {
var contactGlobalID globalID
err := contactGlobalID.FromString(input.ContactID)
if err != nil {
return nil, err
}

req := &entity.Contact{
ID: input.ContactID,
ID: contactGlobalID.ID,
}

contact, err := r.client.ContactRemove(ctx, req)
Expand All @@ -85,8 +97,14 @@ func (r *mutationResolver) ContactUpdate(ctx context.Context, input model.Contac
return nil, errors.New("contact update without a displayName is not currently supported")
}

var contactGlobalID globalID
err := contactGlobalID.FromString(input.ContactID)
if err != nil {
return nil, err
}

req := entity.Contact{
ID: input.ContactID,
ID: contactGlobalID.ID,
DisplayName: *input.DisplayName,
}

Expand All @@ -102,8 +120,24 @@ func (r *mutationResolver) ContactUpdate(ctx context.Context, input model.Contac
}

func (r *mutationResolver) ConversationCreate(ctx context.Context, input model.ConversationCreateInput) (*model.ConversationCreatePayload, error) {
membersID := make([]string, len(input.ContactsID))
for i, cid := range input.ContactsID {
gid := globalID{}
err := gid.FromString(cid)
if err != nil {
return nil, err
}

membersID[i] = gid.ID
}

members, err := memberSliceFromContactIds(input.ContactsID)
if err != nil {
return nil, err
}

req := &entity.Conversation{
Members: memberSliceFromContactIds(input.ContactsID),
Members: members,
}

conversation, err := r.client.ConversationCreate(ctx, req)
Expand All @@ -118,11 +152,22 @@ func (r *mutationResolver) ConversationCreate(ctx context.Context, input model.C
}

func (r *mutationResolver) ConversationInvite(ctx context.Context, input model.ConversationInviteInput) (*model.ConversationInvitePayload, error) {
var conversationGlobalID globalID
err := conversationGlobalID.FromString(input.ConversationID)
if err != nil {
return nil, err
}

members, err := memberSliceFromContactIds(input.ContactsID)
if err != nil {
return nil, err
}

req := &service.ConversationManageMembersInput{
Conversation: &entity.Conversation{
ID: input.ConversationID,
ID: conversationGlobalID.ID,
},
Members: memberSliceFromContactIds(input.ContactsID),
Members: members,
}

conversation, err := r.client.ConversationInvite(ctx, req)
Expand All @@ -137,11 +182,22 @@ func (r *mutationResolver) ConversationInvite(ctx context.Context, input model.C
}

func (r *mutationResolver) ConversationExclude(ctx context.Context, input model.ConversationExcludeInput) (*model.ConversationExcludePayload, error) {
var conversationGlobalID globalID
err := conversationGlobalID.FromString(input.ConversationID)
if err != nil {
return nil, err
}

members, err := memberSliceFromContactIds(input.ContactsID)
if err != nil {
return nil, err
}

req := &service.ConversationManageMembersInput{
Conversation: &entity.Conversation{
ID: input.ConversationID,
},
Members: memberSliceFromContactIds(input.ContactsID),
Members: members,
}

conversation, err := r.client.ConversationExclude(ctx, req)
Expand All @@ -156,9 +212,15 @@ func (r *mutationResolver) ConversationExclude(ctx context.Context, input model.
}

func (r *mutationResolver) ConversationAddMessage(ctx context.Context, input model.ConversationAddMessageInput) (*model.ConversationAddMessagePayload, error) {
var conversationGlobalID globalID
err := conversationGlobalID.FromString(input.ConversationID)
if err != nil {
return nil, err
}

req := &service.ConversationAddMessageInput{
Conversation: &entity.Conversation{
ID: input.ConversationID,
ID: conversationGlobalID.ID,
},
Message: &entity.Message{
Text: input.Message,
Expand Down
6 changes: 3 additions & 3 deletions core/api/node/graphql/service.gen.graphql

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6871bc9

Please sign in to comment.