-
Notifications
You must be signed in to change notification settings - Fork 50
Resources #23
Conversation
rc -> proxy("/" + arg("endpoint", rc) + "/" + arg("id", rc), rc)), | ||
Route.async( | ||
"PATCH", BASE + "/<endpoint>/<id>", | ||
rc -> proxy("/" + arg("endpoint", rc) + "/" + arg("id", rc), rc)) |
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.
You might want to replace these all with just a /<endpoint:path>
parameter that will match the rest of the uri. see https://github.com/spotify/apollo/blob/master/apollo-api/docs/routing-engine.md#path-parameters
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.
Thanks, was thinking of that but didn't know how to do it :)
resource = OBJECT_MAPPER.readValue(payload.get().toByteArray(), Resource.class); | ||
} catch (IOException e) { | ||
return Response.forStatus(Status.BAD_REQUEST.withReasonPhrase("Invalid payload.")); | ||
} |
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.
Use the EntityMiddleware to avoid having to do manual parsing and error handling.
@JsonCreator | ||
public static DataEndpoint create( | ||
@JsonProperty("id") String id, | ||
@JsonProperty("partitioning") Partitioning partitioning, | ||
@JsonProperty("docker_image") Optional<String> dockerImage, | ||
@JsonProperty("docker_args") Optional<List<String>> dockerArgs, | ||
@JsonProperty("secret") Optional<Secret> secret) { | ||
@JsonProperty("secret") Optional<Secret> secret, | ||
@JsonProperty("resources") Optional<List<String>> resources) { |
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 jackson can handle parsing a missing key directly into an empty list, without having to wrap it in an optional. For the resources
field, a missing key and an empty list should have the same meaning.
public abstract String id(); | ||
|
||
@JsonProperty | ||
public abstract long concurrency(); |
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.
Do we want to call it concurrency
or limit
? "Resource limit" sounds more natural to me than a "Resource concurrency".
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 word limit
might not convey that it gets replenished after use. Maybe we can look into what wording thread pools use?
json(), "DELETE", BASE + "/<rid>", | ||
rc -> deleteResource(arg("rid", rc))), | ||
Route.with( | ||
json(), "PATCH", BASE + "/<rid>", |
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.
Shouldn't this be PUT?
@@ -451,7 +451,8 @@ private TriggerListener trigger( | |||
|
|||
return (workflow, triggerId, instant) -> { | |||
try { | |||
if (!storage.enabled(workflow.id()) || !storage.globalEnabled()) { | |||
final Set<WorkflowId> enabledWorkflows = storage.enabledWorkflows(); |
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.
Unrelated change? Why get all the enabled workflows instead of just checking for a specific one?
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 it was changed because enabled(WorkflowId)
is deprecated, then use storage.workflowState
instead.
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.
Thanks!
|
||
Resource getResource(String id) { | ||
return entityToResource( | ||
datastore.get(datastore.newKeyFactory().kind(KIND_RESOURCE).newKey(id))); |
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.
Potential NPE if the lookup does not find a result.
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.
Thanks!
} | ||
|
||
void postResource(Resource resource) { | ||
datastore.put(resourceToEntity(resource)); |
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.
Wrap in retries?
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.
Thanks!
@@ -20,9 +20,11 @@ | |||
|
|||
package com.spotify.styx.storage; | |||
|
|||
import com.google.bigtable.repackaged.com.google.common.collect.ImmutableList; |
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.
Shaded import
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.
Thanks!
@@ -116,14 +117,14 @@ | |||
* @return true if the queried workflow is enabled | |||
*/ | |||
@Deprecated | |||
boolean enabled(WorkflowId workflowId) throws IOException; | |||
boolean isWorkflowEnabled(WorkflowId workflowId) throws IOException; |
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.
These were named with the argument type in mind, like store(Workflow)
, delete(WorkflowId)
, enabled(WorkflowId)
.
The names are all repetitive now with storeWorkflow(Workflow)
.
I can see that the last one is be better as isEnabled(WorkflowId)
, though.
If we want to rename them, then maybe the metric names in MeteredStorage
should be aligned too.
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.
Ah, forgot about the strings in MeteredStorage
. Will have another pass at 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.
Will keep enabledWorkflows
and isEnabled
but revert the others
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.
Will revert all names :)
d688cb8
to
0992ccf
Compare
return Optional.of(entityToResource(entity)); | ||
} | ||
|
||
void postResource(Resource resource) throws IOException { |
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.
No transaction needed when only doing one operation
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.
Fixed, thanks!
1322c76
to
b5df9e3
Compare
@bergman should we wait for cli and tests or are you doing them as separate prs? |
Let's do CLI and tests in a separate PR if you need this now. Just know that this code has never been actually run against datastore (mocked or otherwise). |
Then we should at least do tests in this PR. |
return Api.Version.V1.prefix() + ResourceResource.BASE + path; | ||
} | ||
|
||
private Connection setupBigTableMockTable() { |
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.
Do we have to set up mocked behaviour for bigtable for this test? I think it would be enough just to send in a plain mock, since none of the paths will interact with bigtable.
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.
you're right, will mock instead
awaitResponse(serviceHelper.request("GET", path(""))); | ||
|
||
assertThat(response, hasStatus(belongsToFamily(StatusType.Family.SUCCESSFUL))); | ||
System.out.println("response.payload().get().utf8() = " + response.payload().get().utf8()); |
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.
println
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.
doh!
awaitResponse(serviceHelper.request("PUT", path("/resource2"), | ||
ByteString.encodeUtf8("{\"id\": \"resource2\", \"concurrency\": 3}"))); | ||
assertThat(putResponse, hasStatus(belongsToFamily(StatusType.Family.SUCCESSFUL))); | ||
assertJson(putResponse, "id", equalTo("resource2")); |
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.
Try not to assert things that are not essential for the test. Checking the put response object is already done in the shouldUpdateResource
test case.
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.
yup, same for first listing i guess, it's the same case as shouldListMultipleResources
except that one doesn't POST
but uses datastore directly
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.
hmm, but it makes sense there actually, will keep 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.
Yeah I was thinking about that but then thought that it makes sense to test that the changes are actually reflected in the api. But checking the put response is not directly related.
LGTM 👍 |
Missing: