-
Notifications
You must be signed in to change notification settings - Fork 311
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
Use implicit field mask paths in IS #249
Conversation
Setting prio/high as this is required for |
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.
Not explicitly requesting changes/approving, since I don't understand what's going on
if len(req.FieldMask.Paths) == 0 { | ||
req.FieldMask.Paths = updatePaths | ||
} | ||
if ttnpb.HasAnyField(req.FieldMask.Paths, "contact_info") { |
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 will not evaluate to true
if any of the child paths in contact_info
, e.g. contact_info.contact_type
is set(https://github.com/TheThingsNetwork/lorawan-stack/blob/master/api/contact_info.proto#L45)
Is that expected behavior?
Additionally, it seems like contact_info
is not part of allowed fieldmasks of any PRC at https://github.com/TheThingsNetwork/lorawan-stack/blob/9e35fc3e7bf1ce817076ed39a916914e1b739de7/pkg/ttnpb/field_mask_validation.go at all.
How is this supposed to work?
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.
contact_info
is a slice. Field mask paths don't recurse into slices.- EndDevice doesn't have a
contact_info
field. For applications and other entities, the allowed paths come fromttnpb.ApplicationFieldPathsNested
etc.
@@ -83,6 +83,7 @@ func (is *IdentityServer) getApplication(ctx context.Context, req *ttnpb.GetAppl | |||
if err = is.RequireAuthenticated(ctx); err != nil { | |||
return nil, err | |||
} | |||
req.FieldMask.Paths = cleanFieldMaskPaths(ttnpb.ApplicationFieldPathsNested, req.FieldMask.Paths, getPaths, nil) |
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.
Why is this necessary?
Why not just set this to getPaths
if len(req.FieldMask.Paths) == 0
?
Basically the same question for all other invocations - I really don't get what's going on here.
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.
getPaths
contains the fields that are implicitly part of the field mask, so they are always added to the field mask in the request, if it doesn't already contain them.
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.
Yeah, but there's no harm in adding a field twice - you can just append the fields - we do the same in JS/NS and AS AFAIK.
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.
In order to construct the slice of required fields, Set
registry endpoint in NS constructs a gets
and sets
:
lorawan-stack/pkg/networkserver/grpc_deviceregistry.go
Lines 49 to 57 in 59154c3
gets := append(req.FieldMask.Paths[:0:0], req.FieldMask.Paths...) | |
if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_state.device_class") { | |
gets = append(gets, | |
"mac_state.current_parameters", | |
"mac_state.desired_parameters", | |
"queued_application_downlinks", | |
) | |
} | |
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 is not the NS/JS. In the IS we prefer to have paths in the field mask only once.
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.
But then why not ttnpb.EnsureFieldpaths(paths []string, ensure ...string) []string
?
You pass the existing fieldmask and the paths you want to add if missing.
You don't need 4 arguments for that.
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.
There is no ttnpb.EnsureFieldPaths
, I want to combine this with the allowed paths, I want to be able to specify paths that need to be deleted if present, and finally, I want to do it in a single pass instead of combining EnsureFieldPaths
, EnsureNotFieldPaths
, IntersectFieldPaths
, UniqueFieldPaths
.
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.
- We have API layer middleware, which should validate that fields that should not be present are not present.
- Invalid fieldpaths, which still could get through should be validated explicitly and if present - throw an error.
RPC implementation simply should not delete anything passed to it. Cleaning and validation belongs to the API layer middleware. RPC should simply upsert the required fields.
Summary:
Since #69 (specifically the decisions in #69 (comment) and related meeting) we now allow empty field masks. This PR makes sure that the Identity Server handles such requests accordingly.
Changes:
Notes for Reviewers:
@rvolosatovs if you think it could be useful in other places (end device registries), we can move the
cleanFieldMaskPaths
utility tottnpb
.Release Notes: (optional)
The Identity Server now treats empty field masks as if ids and created/updated times were requested.