Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
0ffde1a6
Commit
0ffde1a6
authored
Oct 13, 2016
by
attiyaishaque
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ECOM-5281 Adding retries and celery task for sending activation email.
parent
82345810
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
118 additions
and
16 deletions
+118
-16
cms/envs/common.py
+4
-0
common/djangoapps/student/tasks.py
+50
-0
common/djangoapps/student/tests/test_create_account.py
+1
-1
common/djangoapps/student/tests/test_tasks.py
+54
-0
common/djangoapps/student/views.py
+6
-15
lms/envs/common.py
+3
-0
No files found.
cms/envs/common.py
View file @
0ffde1a6
...
...
@@ -1208,3 +1208,7 @@ COMPREHENSIVE_THEME_LOCALE_PATHS = []
# to generating test databases will discover and try to create all tables
# and this setting needs to be present
OAUTH2_PROVIDER_APPLICATION_MODEL
=
'oauth2_provider.Application'
# Used with Email sending
RETRY_ACTIVATION_EMAIL_MAX_ATTEMPTS
=
5
RETRY_ACTIVATION_EMAIL_TIMEOUT
=
0.5
common/djangoapps/student/tasks.py
0 → 100644
View file @
0ffde1a6
"""
This file contains celery tasks for sending email
"""
import
logging
from
django.conf
import
settings
from
django.core
import
mail
from
celery.task
import
task
# pylint: disable=no-name-in-module, import-error
from
celery.exceptions
import
MaxRetriesExceededError
from
boto.exception
import
NoAuthHandlerFound
log
=
logging
.
getLogger
(
'edx.celery.task'
)
@task
(
bind
=
True
)
def
send_activation_email
(
self
,
subject
,
message
,
from_address
,
dest_addr
):
"""
Sending an activation email to the users.
"""
max_retries
=
settings
.
RETRY_ACTIVATION_EMAIL_MAX_ATTEMPTS
retries
=
self
.
request
.
retries
try
:
mail
.
send_mail
(
subject
,
message
,
from_address
,
[
dest_addr
],
fail_silently
=
False
)
# Log that the Activation Email has been sent to user without an exception
log
.
info
(
"Activation Email has been sent to User {user_email}"
.
format
(
user_email
=
dest_addr
))
except
NoAuthHandlerFound
:
# pylint: disable=broad-except
log
.
info
(
'Retrying sending email to user {dest_addr}, attempt # {attempt} of {max_attempts}'
.
format
(
dest_addr
=
dest_addr
,
attempt
=
retries
,
max_attempts
=
max_retries
))
try
:
self
.
retry
(
countdown
=
settings
.
RETRY_ACTIVATION_EMAIL_TIMEOUT
,
max_retries
=
max_retries
)
except
MaxRetriesExceededError
:
log
.
error
(
'Unable to send activation email to user from "
%
s" to "
%
s"'
,
from_address
,
dest_addr
,
exc_info
=
True
)
except
Exception
:
# pylint: disable=bare-except
log
.
exception
(
'Unable to send activation email to user from "
%
s" to "
%
s"'
,
from_address
,
dest_addr
,
exc_info
=
True
)
raise
Exception
common/djangoapps/student/tests/test_create_account.py
View file @
0ffde1a6
...
...
@@ -233,7 +233,7 @@ class TestCreateAccount(TestCase):
request
.
user
=
AnonymousUser
()
with
mock
.
patch
(
'edxmako.request_context.get_current_request'
,
return_value
=
request
):
with
mock
.
patch
(
'django.co
ntrib.auth.models.User.email_user
'
)
as
mock_send_mail
:
with
mock
.
patch
(
'django.co
re.mail.send_mail
'
)
as
mock_send_mail
:
student
.
views
.
create_account
(
request
)
# check that send_mail is called
...
...
common/djangoapps/student/tests/test_tasks.py
0 → 100644
View file @
0ffde1a6
"""
Tests for the Sending activation email celery tasks
"""
import
mock
from
django.test
import
TestCase
from
django.conf
import
settings
from
student.tasks
import
send_activation_email
from
boto.exception
import
NoAuthHandlerFound
from
lms.djangoapps.courseware.tests.factories
import
UserFactory
class
SendActivationEmailTestCase
(
TestCase
):
"""
Test for send activation email to user
"""
def
setUp
(
self
):
""" Setup components used by each test."""
super
(
SendActivationEmailTestCase
,
self
)
.
setUp
()
self
.
student
=
UserFactory
()
@mock.patch
(
'time.sleep'
,
mock
.
Mock
(
return_value
=
None
))
@mock.patch
(
'student.tasks.log'
)
@mock.patch
(
'django.core.mail.send_mail'
,
mock
.
Mock
(
side_effect
=
NoAuthHandlerFound
))
def
test_send_email
(
self
,
mock_log
):
"""
Tests retries when the activation email doesn't send
"""
from_address
=
'task_testing@example.com'
email_max_attempts
=
settings
.
RETRY_ACTIVATION_EMAIL_MAX_ATTEMPTS
# pylint: disable=no-member
send_activation_email
.
delay
(
'Task_test'
,
'Task_test_message'
,
from_address
,
self
.
student
.
email
)
# Asserts sending email retry logging.
for
attempt
in
range
(
email_max_attempts
):
mock_log
.
info
.
assert_any_call
(
'Retrying sending email to user {dest_addr}, attempt # {attempt} of {max_attempts}'
.
format
(
dest_addr
=
self
.
student
.
email
,
attempt
=
attempt
,
max_attempts
=
email_max_attempts
))
self
.
assertEquals
(
mock_log
.
info
.
call_count
,
6
)
# Asserts that the error was logged on crossing max retry attempts.
mock_log
.
error
.
assert_called_with
(
'Unable to send activation email to user from "
%
s" to "
%
s"'
,
from_address
,
self
.
student
.
email
,
exc_info
=
True
)
self
.
assertEquals
(
mock_log
.
error
.
call_count
,
1
)
common/djangoapps/student/views.py
View file @
0ffde1a6
...
...
@@ -56,6 +56,7 @@ from student.models import (
DashboardConfiguration
,
LinkedInAddToProfileConfiguration
,
ManualEnrollmentAudit
,
ALLOWEDTOENROLL_TO_ENROLLED
,
LogoutViewConfiguration
,
RegistrationCookieConfiguration
)
from
student.forms
import
AccountCreationForm
,
PasswordResetFormNoActive
,
get_registration_extension_form
from
student.tasks
import
send_activation_email
from
lms.djangoapps.commerce.utils
import
EcommerceService
# pylint: disable=import-error
from
lms.djangoapps.verify_student.models
import
SoftwareSecurePhotoVerification
# pylint: disable=import-error
from
bulk_email.models
import
Optout
,
BulkEmailFlag
# pylint: disable=import-error
...
...
@@ -1812,21 +1813,11 @@ def create_account_with_params(request, params):
'email_from_address'
,
settings
.
DEFAULT_FROM_EMAIL
)
try
:
if
settings
.
FEATURES
.
get
(
'REROUTE_ACTIVATION_EMAIL'
):
dest_addr
=
settings
.
FEATURES
[
'REROUTE_ACTIVATION_EMAIL'
]
message
=
(
"Activation for
%
s (
%
s):
%
s
\n
"
%
(
user
,
user
.
email
,
profile
.
name
)
+
'-'
*
80
+
'
\n\n
'
+
message
)
mail
.
send_mail
(
subject
,
message
,
from_address
,
[
dest_addr
],
fail_silently
=
False
)
else
:
user
.
email_user
(
subject
,
message
,
from_address
)
except
Exception
:
# pylint: disable=broad-except
log
.
error
(
u'Unable to send activation email to user from "
%
s" to "
%
s"'
,
from_address
,
dest_addr
,
exc_info
=
True
)
if
settings
.
FEATURES
.
get
(
'REROUTE_ACTIVATION_EMAIL'
):
dest_addr
=
settings
.
FEATURES
[
'REROUTE_ACTIVATION_EMAIL'
]
message
=
(
"Activation for
%
s (
%
s):
%
s
\n
"
%
(
user
,
user
.
email
,
profile
.
name
)
+
'-'
*
80
+
'
\n\n
'
+
message
)
send_activation_email
.
delay
(
subject
,
message
,
from_address
,
dest_addr
)
else
:
registration
.
activate
()
_enroll_user_in_pending_courses
(
user
)
# Enroll student in any pending courses
...
...
lms/envs/common.py
View file @
0ffde1a6
...
...
@@ -375,6 +375,9 @@ GENERATE_PROFILE_SCORES = False
# Used with XQueue
XQUEUE_WAITTIME_BETWEEN_REQUESTS
=
5
# seconds
# Used with Email sending
RETRY_ACTIVATION_EMAIL_MAX_ATTEMPTS
=
5
RETRY_ACTIVATION_EMAIL_TIMEOUT
=
0.5
############################# SET PATH INFORMATION #############################
PROJECT_ROOT
=
path
(
__file__
)
.
abspath
()
.
dirname
()
.
dirname
()
# /edx-platform/lms
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment