-
-
Notifications
You must be signed in to change notification settings - Fork 193
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
[feature] Emit signal in freeradius accounting view #341 #350
Conversation
158e4aa
to
a410ad9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good, please add the docs.
openwisp_radius/signals.py
Outdated
@@ -0,0 +1,3 @@ | |||
from django.dispatch import Signal | |||
|
|||
radius_accounting_success = Signal(providing_args=['account_data']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please chagne account_data
to accounting_data
here and anywhere else, because account and accounting are two different concepts which must not be confused.
docs/source/user/api.rst
Outdated
- ``accounting_data``: accounting information | ||
|
||
This signal is emitted every time accounting information is added or updated. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please let's add a new page as requested in the issue description because this will likely grow in the near future.
docs/source/developer/signals.rst
Outdated
|
||
- ``accounting_data``: accounting information | ||
|
||
This signal is emitted every time accounting information is added or updated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make sure the following concepts are extra clear:
- the signal is emitted every time the accounting REST API endpoint completes successfully
- the signal is emitted right before the response is returned
- accounting_data is a
dict
450bdfd
to
282a383
Compare
@@ -445,6 +448,11 @@ def _data_to_acct_model(self, valid_data): | |||
valid_data['organization'] = acct_org | |||
return valid_data | |||
|
|||
def send_radius_accounting_signal(self, accounting_data): | |||
radius_accounting_success.send( | |||
sender=self.__class__, accounting_data=accounting_data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sender is the view, I noticed only now, it makes sense, but we haven't specified this in the docs, so users would have to dig in the code to find out, which is means the documentation is not good enough. Please fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that it could be useful to pass the view instance (self) instead of the class, because that allows accessing a lot of information about the request and it can be useful to developers who may want to use this signal. Can you please update it here and in the docs?
282a383
to
027d497
Compare
return Response(None, status=201, headers=headers) | ||
else: | ||
serializer = self.get_serializer(instance, data=data, partial=False) | ||
serializer.is_valid(raise_exception=True) | ||
acct_data = self._data_to_acct_model(serializer.validated_data.copy()) | ||
serializer.update(instance, acct_data) | ||
self.send_radius_accounting_signal(acct_data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@devkapilbansal Instead of acct_data
, can we pass serializer.data
?
Because while passing this data to celery I am getting:
kombu.exceptions.EncodeError: Object of type Organization is not JSON serializable
_data_to_acct_model
removes status_type
and adds organization
. Also, status_type
is more required in detecting the radius status i.e. Start
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense.
@@ -445,6 +448,11 @@ def _data_to_acct_model(self, valid_data): | |||
valid_data['organization'] = acct_org | |||
return valid_data | |||
|
|||
def send_radius_accounting_signal(self, accounting_data): | |||
radius_accounting_success.send( | |||
sender=self.__class__, accounting_data=accounting_data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that it could be useful to pass the view instance (self) instead of the class, because that allows accessing a lot of information about the request and it can be useful to developers who may want to use this signal. Can you please update it here and in the docs?
ef50247
to
2ce3de0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good now 👍
I will do some manual testing and then merge it.
@@ -445,6 +448,9 @@ def _data_to_acct_model(self, valid_data): | |||
valid_data['organization'] = acct_org | |||
return valid_data | |||
|
|||
def send_radius_accounting_signal(self, accounting_data): | |||
radius_accounting_success.send(sender=self, accounting_data=accounting_data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we are passing self
from here it is a view object which we can't specify as sender while connecting to receivers.
We must use __class__
to get the class view and not the view object.
cc: @nemesisdesign
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@codesankalp we know it's a view instance, the change was done on purpose (django also passes view instances), what is the problem you're trying to describe? I don't understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I think I understand now, in this case we don't need to take into account the sender though, because only this class will send this. Let's look at how django implements some of their request cycle signals and do it similarly (let's look if they use the view instance or class as sender).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@devkapilbansal Sankalp is right, let's do the following which should be more ortodox:
- restore the previous sender (the class)
- pass the request and view instance as an additional argument
- update docs
openwisp_radius/signals.py
Outdated
@@ -0,0 +1,3 @@ | |||
from django.dispatch import Signal | |||
|
|||
radius_accounting_success = Signal(providing_args=['accounting_data']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
providing_args
doesn't play well with django 4 in which it was removed, please see the release notes of django 4 (lookfor providing_args
) and update this code according to what is suggested there.
@@ -445,6 +448,9 @@ def _data_to_acct_model(self, valid_data): | |||
valid_data['organization'] = acct_org | |||
return valid_data | |||
|
|||
def send_radius_accounting_signal(self, accounting_data): | |||
radius_accounting_success.send(sender=self, accounting_data=accounting_data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@devkapilbansal Sankalp is right, let's do the following which should be more ortodox:
- restore the previous sender (the class)
- pass the request and view instance as an additional argument
- update docs
2ce3de0
to
5942fbd
Compare
5942fbd
to
d8385e3
Compare
d8385e3
to
9a1d2e2
Compare
Closes #341