-
Notifications
You must be signed in to change notification settings - Fork 0
update and delete functions now take an optional rule-set-version #59
Conversation
public/r2/v1/swagger/swagger.json
Outdated
"$ref": "#/definitions/MappingRule" | ||
"type": "object", | ||
"properties": { | ||
"rollup-rule": { |
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.
Should this be called mapping-rule?
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.
oops.
public/r2/v1/swagger/swagger.json
Outdated
@@ -442,7 +464,7 @@ | |||
"200": { | |||
"description": "Ruleset updated", | |||
"schema": { | |||
"$ref": "#/definitions/ApiResponse" | |||
"$ref": "#/definitions/DeleteResponse" |
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.
A little confused about the DeleteResponse here - why do we need to return the version for 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.
well, the version is for a rule set and this operation updates the current ruleset snapshot, there will be one less rule. If you then wanted to do further modifications after the delete you would be operating on a stale version of the rule set so it needs to be returned.
b9d9cf3
to
41dd2c3
Compare
Updated this PR with a different approach. I have added a bulk update endpoint where a set of changes to a ruleset can be submitted. There is a flag which will apply all the updates either atomically or not based on the atomic flag. Initially, only atomic operations will be supported. This endpoint accepts a rule-set-verison which will be used as a |
571ad04
to
be710d3
Compare
fe30074
to
58c4aeb
Compare
"parameters": [ | ||
{ | ||
"in": "path", | ||
"name": "namespaceID", |
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 probably unnecessary to be required. You are updating the resource which is in the URL, so this can be inferred.
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.
Interesting. I took a look at the other endpoint URIs and it looked like they required parameters that were part of the URL. Perhaps we should keep if for consistency.
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.
If thats the case, then lets keep it consistent
public/r2/v1/swagger/swagger.json
Outdated
{ | ||
"in": "body", | ||
"name": "rule-set-version", | ||
"description": "The ruleset version to update, for check and set operations", |
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.
If this isn't passed, will it skip this check-set validation? If so, let's make a comment in the description 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.
This should actually be required. I was thinking that if you did things non-atomically you would not need to pass this, but I was wrong about that, but it should always be required.
"$ref": "#/definitions/ApiResponse" | ||
} | ||
}, | ||
"409": { |
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 would this occur? This is a PUT. This implies that we are creating something via a POST
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.
A 409 is the case when you provide a rule-set-version that is stale.
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.
Should the description clarify 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 see. The description here is a little confusing. But I think a 409 is still relevant.
public/r2/v1/swagger/swagger.json
Outdated
}, | ||
{ | ||
"in": "body", | ||
"name": "atomic", |
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.
Actually on a second thought, we probably don't need this to begin with and always require a ruleset version to start with. We can always relax that constraint later if needed.
public/r2/v1/swagger/swagger.json
Outdated
@@ -863,20 +936,80 @@ | |||
"type": "integer", | |||
"format": "unixMillis" | |||
}, | |||
"mappingRules": { | |||
"mappingRulesChanges": { |
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 think these should be mapping rules instead of mapping rule changes?
public/r2/v1/swagger/swagger.json
Outdated
"type": "array", | ||
"items": { | ||
"$ref": "#/definitions/MappingRule" | ||
} | ||
}, | ||
"rollupRules": { | ||
"rollupRulesChanges": { |
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 think these should be rollup rules instead of rollup rule changes?
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 should have caught this. I think this was bad find and replace.
d099d1a
to
6ab39b8
Compare
public/r2/v1/swagger/swagger.json
Outdated
@@ -84,7 +84,7 @@ | |||
} | |||
}, | |||
"409": { | |||
"description": "Namespace already exists", | |||
"description": "The ruleset got updated while you were looking at it.", |
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.
Hm I thought we'd return 409 when the namespace already existed? If someone calls this API programmatically without checking whether the namespace exists beforehand, they can get 409 if they try to create a namespace that exists. If so, probably wanna keep it as "Namespace already exists"?
public/r2/v1/swagger/swagger.json
Outdated
@@ -184,6 +184,72 @@ | |||
} | |||
} | |||
}, | |||
"/namespaces/{namespaceID}/ruleset/bulk": { | |||
"put": { |
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.
Should this be POST rather than PUT since calling this endpoint twice with the same set of changes are not idempotent?
public/r2/v1/swagger/swagger.json
Outdated
"tags":[ | ||
"namespaces" | ||
], | ||
"summary": "Bulk update endpoint for namespace changes", |
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.
nit: for ruleset changes
.
public/r2/v1/swagger/swagger.json
Outdated
}, | ||
{ | ||
"in": "body", | ||
"name": "rule-set-version", |
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.
Should this be ruleset-version
instead of rule-set-version
?
public/r2/v1/swagger/swagger.json
Outdated
{ | ||
"in": "body", | ||
"name": "rule-set-version", | ||
"description": "The ruleset version to update, for check and set operations", |
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.
nit: might be more clear to say "The ruleset version to atomically apply bulk updates against"
public/r2/v1/swagger/swagger.json
Outdated
"properties": { | ||
"operation": { | ||
"type": "string", | ||
"enum": ["add", "remove", "change"], |
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.
Does this mean we might add / delete namespace as part of the bulk operation? Might wanna think about if we want to allow that given that we already have APIs for adding new namespaces and deleting existing namespaces?
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 was something I was thinking about. It does seem like this endpoint would be more simple if we did not allow for these types of operations, but if users are going to be hitting this endpoint programmatically it might be easier to have a one-stop endpoint for manipulating rules. I can remove it for now and if we need to add it back later we can.
public/r2/v1/swagger/swagger.json
Outdated
}, | ||
"from": { | ||
"$ref": "#/definitions/MappingRuleData", | ||
"description": "old version of rule" |
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.
Perhaps better to say "old rule data"?
Also this can be null for "add" and "change" operations I assume?
public/r2/v1/swagger/swagger.json
Outdated
}, | ||
"to": { | ||
"$ref": "#/definitions/MappingRuleData", | ||
"description": "new version of rule" |
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.
Perhaps better to say "new rule data"?
Also this can be null for "remove" operations I assume?
public/r2/v1/swagger/swagger.json
Outdated
}, | ||
"from": { | ||
"$ref": "#/definitions/RollupRuleData", | ||
"description": "old version of rule" |
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.
Perhaps better to say "old rule data"?
Also this can be null for "add" and "change" operations I assume?
public/r2/v1/swagger/swagger.json
Outdated
}, | ||
"to": { | ||
"$ref": "#/definitions/RollupRuleData", | ||
"description": "new version of rule" |
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.
Perhaps better to say "new rule data"?
Also this can be null for "remove" operations I assume?
d0b55ae
to
1a51f57
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.
LGTM.
public/r2/v1/swagger/swagger.json
Outdated
"properties": { | ||
"operation": { | ||
"type": "string", | ||
"enum": ["add", "remove", "change"], |
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.
Can we please change remove
to delete
for consistency? That's what we use in m3metrics as well.
m3ctrl right now relies on tradition CRUD semantics for interacting with rules. With the current implementation, we are not able to do a check and set operation which are very powerful in a distributed systems setting. Right now the underlying storage layer of m3ctl is KV, which provides a check and set method for data with a given version. This diff updates the HTTP/JSON interface to accept a rule-set-version on rule updates and deletes so that we take advantage of KV check and sets.
NOTE:
Currently, if you query a single rule it does not return a rule-set-version. This means in order to update a rule and use check and set you would need to query the entire rule set, which does return a rule-set-version, then make your change with the version. I think it is reasonable to have those endpoints return a version number, however, it may be better to add those in a separate PR.
In all cases, I have not made the rule-set-version fields required. This will not break API backward compatibility. I am not sure the best way to go forward here. On one hand, we could say that if these fields are omitted then we skip the check and set, but that is potentially dangerous. The other options are to make it required and break back compat, and fix the UI, or create v2 endpoints. I am personally in the create a new version camp, as it will be much less complicated than making it optional while making the API cleaner. The final solution is to break back compat but that should be avoided whenever possible.