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

Delete users in segment when they are deleted from system #717

Merged
merged 7 commits into from
May 9, 2019

Conversation

Martouta
Copy link
Contributor

@Martouta Martouta commented Mar 21, 2019

Closes THREESCALE-1846 - Delete users in segment when they are deleted from system
We will need https://github.com/3scale/deploy/pull/550 merged for it to work, but without it, it simply does nothing 😄

Tasks of this PR

  • Add a SegmentDeletionConfig as a config feature containing : enabled, email, password, uri, workspace.
  • When a User is destroyed, save a simple UserDeletedEvent. The only data we need is the user ID and the tenant ID.
  • Segment::AuthenticatorService to request token. It uses Faraday and raises an error for wrong responses.
  • Segment::DeleteUserService to delete the user from the user_id it receives and with the token sent as param.
  • When the UserDeletedEvent is created, it is destroyed in segment in the background
  • When segment deletion feature is disabled, do not even enqueue the worker
  • Remove all the code of the old SegmentSubscriber.
  • Remove programatically the first_admin_id of Account.

Why to remove the SegmentSubscriber

the SegmentSubscriber to call segment for the accounts that were deleted to mark their first admin as 'state: deleted' in segment. It was by account and we want it for user, and it didn't delete it for real them for real but just put that state attribute on them.

Why to remove the first_admin_id

Some of the times this explanation has been requested are: #717 (comment) & #717 (comment) & #717 (comment)

The first_admin_id was introduced in #8 to fix this bug https://github.com/3scale/porta/issues/10 . It was introduced 5 months ago. The problem was that AccountDeletedEvent was saving the user_id of the first admin but at the time this event was being saved, the user had already been deleted and we didn't have the ID anymore. And we needed it only for the SegmentSubscriber. Now that we have removed the SegmentSubscriber, we don't need the first_admin_id at all anymore. Although that time has changed it is not used anywhere else for anything:
image

In preview only seen that the configuration is correct

I checked in preview that the configuration of Features::SegmentDeletionConfig is correct for https://github.com/3scale/deploy/pull/550, and then I am testing locally in development environment with that same configuration... with the production one though, and using the list of users that need to be destroyed for real...
These are the reasons:

  1. Apparently we don't always do the tracking thing when we create new providers, which is probably a bug. When it goes through some specific controllers and ProviderAccountManager, i think it doesn't happen. Anyway, if this is a bug, it is not a bug problem for this issue by itself, we still need to figure it out because if it is a bug, we need to create a jira issue for this, but we can bypass this problem for this testing because we can execute the Account.master.third_party_notifications!(tenant) for this method.
  2. Even bypassing the previous one, i don't see anything created in segment because:
    2.1 We are not specifying this workspace and url for preview anywhere, so it is impossible that it goes there to create the users
    2.2 In segment we can not see the users itself, we need integration with intercom, and apparently there is an intercom for testing but i couldn't access it...

Verification steps (locally and with real production data, so be careful with this!)

  1. Open a terminal and checkout to this Git branch.
  2. Edit the file config/features.yml to have a config that can access to the production data. You can see the proper format in config/examples/features.yml and the proper data in https://github.com/3scale/deploy/pull/550
  3. Edit the following method to return true always, so you can delete any user.

    porta/app/models/user.rb

    Lines 416 to 419 in 3f7fa1d

    def destroyable?
    return true if destroyed_by_association
    !(account && !account.destroyed? && account.admins == [self])
    end
  4. Optional step, but personally I reseted the whole local DB and I have done redis-cli flushall to have all the sidekiq queue clean.
  5. Either create a user or use one of the users that you already have in the DB, either way got to the rails console and do User.last.update_column(:id, user_id) with the user_id of one of those that have to be destroyed for real and has not been destroyed yet.
  6. Close the rails console, stop spring if you have it running (spring stop). Turn on the Rails Server: OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES UNICORN_WORKERS=8 bundle exec rails server -b 0.0.0.0
  7. In another tab of the terminal, turn on Sidekiq with the default queue: UNICORN_WORKERS=8 bundle exec sidekiq -q low -q default -L log/sidekiq.log
  8. In another tab of the terminal, check the logs of Sidekiq: tail -f log/sidekiq.log
  9. In the UI, go to the user edit page and delete it, in many case it was in http://provider-admin.example.com.lvh.me:3000/buyers/accounts/3/users/:user_id/edit.
  10. You should see in the logs of Sidekiq something like this:
2019-05-06T15:00:00.051Z 19691 TID-ox1a4veen SegmentDeleteUserWorker JID-1afb023df04f1c4f4c013d55 INFO: start
...
2019-05-06T15:00:01.827Z 19691 TID-ox1a4veen SegmentDeleteUserWorker JID-1afb023df04f1c4f4c013d55 INFO: done: 1.776 sec
  1. Go the deletion requests page in the Segment page, and see that the user with this ID is already there. You will see that it says FAILED or INITIALIZED, which means that it works.
    The FAILED means that segment does a request to the 3rd party services and the 3rd party services might fail and we can not do anything about it, and for this PR this is still just fine, so for this PR, FAILED would mean it worked, because we got to notify segment, and we would have a problem only if it doesn't appear at all in the deletion requests page in the Segment page.

@Martouta Martouta self-assigned this Mar 21, 2019
@@ -0,0 +1,5 @@
# frozen_string_literal: true

class UserRelatedEvent < BaseEventStoreEvent
Copy link
Member

Choose a reason for hiding this comment

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

@Martouta I assume this is to prepare for other user related events that might be added in the future? Not premature?

Copy link
Member

Choose a reason for hiding this comment

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

Looking at user_related_event_test.rbI guess it's just the way we structure events

Copy link
Contributor Author

@Martouta Martouta Mar 22, 2019

Choose a reason for hiding this comment

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

Yes, it is the way that structure events, and also the way that we structure Subscribers to those events (grouping by 'related' events 😄 )

Copy link
Contributor

Choose a reason for hiding this comment

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

user related event makes sense.

assert_equal event.metadata[:provider_id], master_account.id
end

test 'the event is persisted and with the necessary attributes when its associations are already destroyed' do

This comment was marked as resolved.

@@ -20,6 +20,16 @@ class UserTest < ActiveSupport::TestCase
ActionMailer::Base.deliveries = []
end

test 'the event is created when the user is destroyed' do

This comment was marked as resolved.

Copy link
Member

@thomasmaas thomasmaas left a comment

Choose a reason for hiding this comment

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

left some comments and suggestions to improve test decriptions

@Martouta Martouta force-pushed the user-destroyed-segment-delete branch from 20ce617 to 2042605 Compare March 21, 2019 15:39
@codecov
Copy link

codecov bot commented Mar 21, 2019

Codecov Report

Merging #717 into master will increase coverage by 0.94%.
The diff coverage is 99.65%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #717      +/-   ##
==========================================
+ Coverage      92%   92.94%   +0.94%     
==========================================
  Files        2321     2413      +92     
  Lines       74204    78298    +4094     
==========================================
+ Hits        68269    72777    +4508     
+ Misses       5935     5521     -414
Impacted Files Coverage Δ
test/unit/signup/result_test.rb 100% <ø> (ø) ⬆️
app/events/accounts/account_deleted_event.rb 100% <ø> (ø) ⬆️
test/unit/logic/provider_signup_test.rb 98.59% <ø> (ø)
app/lib/logic/provider_signup.rb 99.18% <ø> (+34.95%) ⬆️
test/unit/user_test.rb 98.84% <100%> (+0.01%) ⬆️
app/lib/features/config.rb 100% <100%> (ø)
app/events/users/user_deleted_event.rb 100% <100%> (ø)
.../unit/services/segment/delete_user_service_test.rb 100% <100%> (ø)
app/lib/event_store/repository.rb 100% <100%> (ø) ⬆️
app/services/segment/unexpected_response_error.rb 100% <100%> (ø)
... and 194 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3f7fa1d...06ab167. Read the comment docs.

@Martouta Martouta force-pushed the user-destroyed-segment-delete branch 7 times, most recently from 1fbeca9 to b442bb9 Compare March 22, 2019 09:47
@Martouta Martouta changed the title [WIP][NOT REVIEWABLE] Delete users in segment when they are deleted from system [WIP] Delete users in segment when they are deleted from system Mar 22, 2019
@Martouta Martouta requested a review from thomasmaas March 22, 2019 09:49
thomasmaas
thomasmaas previously approved these changes Mar 22, 2019
Copy link
Member

@thomasmaas thomasmaas left a comment

Choose a reason for hiding this comment

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

Any way we can test this in preview/staging? (We do have an Intercom staging account, not sure about segment)

@Martouta Martouta force-pushed the user-destroyed-segment-delete branch 3 times, most recently from 7b16e91 to a35cfc9 Compare March 22, 2019 14:05
@Martouta Martouta force-pushed the user-destroyed-segment-delete branch 3 times, most recently from bc79dbb to d443efc Compare March 22, 2019 15:02
end

def self.config
configuration.config
Copy link
Contributor

Choose a reason for hiding this comment

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

this is an instance variable on class level? 🇫🇷

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@macejmic Yes 😂 It was originally a module because we only need one global config for a feature, but @hallelujah explained me that it is better to have it like a class, the variable @configuration of the class (which is one of the instances) is the global configuration for the feature, and we can have as many instances as we want with different configs to test them in isolation without having to do dirty stuff from the tests like https://github.com/3scale/porta/pull/589/files#diff-02fd35c4c56ad40080442d610f0cc910L7

Copy link
Contributor

Choose a reason for hiding this comment

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

ok, that could work :)

@Martouta Martouta force-pushed the user-destroyed-segment-delete branch 2 times, most recently from 06276b6 to 378b905 Compare March 22, 2019 15:31
@Martouta
Copy link
Contributor Author

Martouta commented Mar 22, 2019

[OUTDATED COMMENT! 😉 ]
As I explained to @thomasmaas and in the sync to everyone before, we can't test this in preview because we would delete real data.
We can test it locally, carefully, with users that we KNOW for sure that should be deleted anyway 😄

@Martouta Martouta changed the title [WIP] Delete users in segment when they are deleted from system Delete users in segment when they are deleted from system Mar 22, 2019
@Martouta Martouta force-pushed the user-destroyed-segment-delete branch from 497e89b to 974cede Compare April 25, 2019 08:40
macejmic
macejmic previously approved these changes Apr 25, 2019
@Martouta Martouta requested a review from guicassolato April 25, 2019 08:41
@Martouta Martouta force-pushed the user-destroyed-segment-delete branch from 974cede to a30bd83 Compare May 6, 2019 14:14
@Martouta Martouta requested review from macejmic and a team May 6, 2019 15:32
@Martouta Martouta changed the title [WIP] Delete users in segment when they are deleted from system Delete users in segment when they are deleted from system May 6, 2019
@Martouta Martouta changed the title Delete users in segment when they are deleted from system [WIP] Delete users in segment when they are deleted from system May 6, 2019
@Martouta Martouta force-pushed the user-destroyed-segment-delete branch from 71a8322 to cf4dd10 Compare May 6, 2019 16:50
@Martouta Martouta force-pushed the user-destroyed-segment-delete branch from cf4dd10 to 1bde827 Compare May 7, 2019 09:08
@Martouta Martouta changed the title [WIP] Delete users in segment when they are deleted from system Delete users in segment when they are deleted from system May 7, 2019
@Martouta Martouta removed the do not review This PR is currently not reviewable label May 7, 2019
Martouta added 3 commits May 7, 2019 18:17
…letedUserEvent is created

When segment deletion feature is disabled, do not even enqueue the worker
1. Feature configs implementation
2. GBPRApiRequest implementation
3. Test of the worker
@Martouta Martouta force-pushed the user-destroyed-segment-delete branch from 1bde827 to 06ab167 Compare May 7, 2019 16:17
# frozen_string_literal: true

module Features
class SegmentDeletionConfig < Config; end
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that I do because we have different types of features (right now AccountDeletionConfig and SegmentDeletionConfig) and we need to load them by type (look at the initializer) and fetch them where we use them by type... and even stub them by type. Almost the whole PR is based on that 🤔 check SegmentDeletionConfig and you will see 15 results so far 😄

Copy link
Contributor

Choose a reason for hiding this comment

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

sounds good to me.

@Martouta Martouta requested review from hallelujah and a team May 8, 2019 09:33
@macejmic
Copy link
Contributor

macejmic commented May 8, 2019

good job! 🍤

Copy link
Contributor

@hallelujah hallelujah left a comment

Choose a reason for hiding this comment

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

Looks good

@Martouta Martouta merged commit 7ebf9c7 into master May 9, 2019
@Martouta Martouta deleted the user-destroyed-segment-delete branch May 9, 2019 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature A new feature of the product Priority: High Closes a JIRA issue in our sprint ruby Pull requests that update Ruby code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants