Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sc 14489: contact migration #1012

Merged
merged 7 commits into from
May 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 94 additions & 1 deletion cmd/gdsutil/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,21 @@ func main() {
},
},
},
{
Name: "contact:migrate",
Usage: "migrate all contacts on vasps into the model contacts namespace",
Category: "contact",
Action: migrateContacts,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "dryrun",
Aliases: []string{"d"},
Usage: "print migration results without modifying the database, used for testing",
Value: true,
},
},
},
}

app.Run(os.Args)
}

Expand Down Expand Up @@ -1244,6 +1257,86 @@ func generateTokenKey(c *cli.Context) (err error) {
return nil
}

func migrateContacts(c *cli.Context) (err error) {
// Create a list of vasp contacts and model contacts
modelContacts := make(map[string]*models.Contact)
var vaspContacts []*pb.Contact

// iterate through all vasps in the database
iter := ldb.NewIterator(util.BytesPrefix([]byte(wire.NamespaceVASPs)), nil)
for iter.Next() {
vasp := new(pb.VASP)
if err = proto.Unmarshal(iter.Value(), vasp); err != nil {
iter.Release()
return cli.Exit(err, 1)
}
iter := models.NewContactIterator(vasp.Contacts, true, false)

// Iterate through all contacts on the vasp
for iter.Next() {
vaspContact, _ := iter.Value()
vaspContacts = append(vaspContacts, vaspContact)
modelContact, AlreadyExists := modelContacts[vaspContact.Email]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may need to make sure the email is normalized before putting it in the map, although if it's coming from the VASP hopefully it will already be.


// Extract the extra fields from the vasp contact
vaspContactExtra := &models.GDSContactExtraData{}
if vaspContact.Extra != nil {
if err = vaspContact.Extra.UnmarshalTo(vaspContactExtra); err != nil {
return fmt.Errorf("could not deserialize previous extra: %s", err)
}
}

// If the model contact doesn't already exist create it,
// if it does update the email log and vasp list
if !AlreadyExists {
modelContact = &models.Contact{
Email: vaspContact.Email,
Name: vaspContact.Name,
Vasps: []string{vasp.CommonName},
Verified: vaspContactExtra.Verified,
Token: vaspContactExtra.Token,
EmailLog: vaspContactExtra.EmailLog,
Created: time.Now().Format(time.RFC3339),
Modified: time.Now().Format(time.RFC3339),
}
} else {
modelContact.Vasps = append(modelContact.Vasps, vasp.CommonName)
if vaspContactExtra.EmailLog != nil {
modelContact.EmailLog = append(modelContact.EmailLog, vaspContactExtra.EmailLog...)
}
}
}
}

// if the dryrun flag is set, print all vasp contacts and the
// newly created model contacts and return
if c.Bool("dryrun") {
fmt.Println("existing vasp contacts:")
for _, contact := range vaspContacts {
fmt.Print(contact)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to newline separate these or something or just print out the emails space separated because this is probably going to be messy when things get printed out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good Idea!

}
fmt.Println() // Print a new line for clarity
fmt.Println("created contacts:")
for _, contact := range modelContacts {
fmt.Print(contact)
}
return nil
}

// Put all new model contacts into the leveldb database
for _, contact := range modelContacts {
var data []byte
key := []byte(wire.NamespaceContacts + "::" + contact.Email)
if data, err = proto.Marshal(contact); err != nil {
return cli.Exit(err, 1)
}
if err = ldb.Put(key, data, nil); err != nil {
return cli.Exit(err, 1)
}
}
return nil
}

//===========================================================================
// Helper Functions
//===========================================================================
Expand Down