-
Notifications
You must be signed in to change notification settings - Fork 52
CASSSIDECAR-360: Sidecar API Endpoint for Nodetool Compaction Stop #272
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
base: trunk
Are you sure you want to change the base?
Conversation
…detool compaction stop API implementation
| else | ||
| { | ||
| // Handler guarantees compactionType is non-null/non-empty | ||
| proxy.stopCompaction(compactionType); |
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.
Maybe we should add a @NotNull annotation to compactionType?
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.
See change on CassandraCompactionManagerOperations line 77 . Not exactly an annotation but a requireNonNull check. Let me know if that's acceptable.
client-common/src/main/java/org/apache/cassandra/sidecar/common/ApiEndpointsV1.java
Outdated
Show resolved
Hide resolved
...-common/src/main/java/org/apache/cassandra/sidecar/common/request/CompactionStopRequest.java
Outdated
Show resolved
Hide resolved
| @JsonInclude(JsonInclude.Include.NON_NULL) | ||
| public class CompactionStopRequestPayload | ||
| { | ||
| private final String compactionType; |
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 an enum instead of a free string?
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.
Chose deliberately to use String, as I figured this would encourage forward compatibility with future C* versions if more compactionTypes are added later. i.e., would want to avoid sidecar forcing all C* versions into a single enum definition, and would rather leave this responsibility to cassandra itself. Would appreciate @arjunashok's input for this though.
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 are already defining the compaction types as a set in AbstractHandler.SUPPORTED_COMPACTION_TYPES. Better to make it an enum instead of a set.
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.
Done
...ommon/src/main/java/org/apache/cassandra/sidecar/common/response/CompactionStopResponse.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/apache/cassandra/sidecar/modules/CassandraOperationsModule.java
Outdated
Show resolved
Hide resolved
| @APIResponse(description = "Compaction stop operation completed", | ||
| responseCode = "200", | ||
| content = @Content(mediaType = "application/json", | ||
| schema = @Schema(implementation = CompactionStopResponse.class))) |
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 add the @apiresponse for the error codes as well
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.
See lines 149-189 of CompactionStopHandler.java - I do some custom error handling here, as particular api response codes will have different messages thrown depending on the input. Let me know if I should still edit this section in CassandraOperationsModule.
sklaha
left a comment
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.
Thank you for the PR. Looks good at a high level. Please run ./gradlew clean; ./gradlew build which will show you check style issues. I am leaving my other comments inline.
server/src/main/java/org/apache/cassandra/sidecar/handlers/CompactionStopHandler.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/apache/cassandra/sidecar/handlers/CompactionStopHandler.java
Show resolved
Hide resolved
...in/java/org/apache/cassandra/sidecar/adapters/base/CassandraCompactionManagerOperations.java
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| @Test | ||
| void testStopCompactionByIdSuccess() |
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 the current implementation, a request with a non-existent compaction ID silently succeeds. The JMX call simply succeeds without any action being taken. It would be more informative to update the Cassandra JMX implementation to return a boolean value or some other indicator. I will seek input from others on this.
...s/src/integrationTest/org/apache/cassandra/sidecar/routes/CompactionStopIntegrationTest.java
Show resolved
Hide resolved
client-common/src/main/java/org/apache/cassandra/sidecar/common/ApiEndpointsV1.java
Outdated
Show resolved
Hide resolved
...-common/src/main/java/org/apache/cassandra/sidecar/common/request/CompactionStopRequest.java
Outdated
Show resolved
Hide resolved
...ommon/src/main/java/org/apache/cassandra/sidecar/common/response/CompactionStopResponse.java
Show resolved
Hide resolved
| public static final String STATUS_KEY = "status"; | ||
| public static final String ERROR_CODE_KEY = "error_code"; |
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 evaluate the intended usage of the error_code field in determining the values. Based on the current name, it seems to suggest this is a status code (currently returning 200 OK)
The 200 status code would be redundant in this case, as it is implied with the HTTP response code.
The other option is to do away with this field since we have a reason field to denote an arbitrary string reason when there is an error (or a non-200 response).
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.
Also, can status be an enum here? Seems like it can be one of 3 or 4 values - SUBMITTED, PENDING or FAILED
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.
Original status options for the command were just two - "PENDING" and "FAILED". For this API it's "SUBMITTED" (more clear I think) and "FAILED".
Status changed to enum - see CompactionStopStatus.java for new enum class
server/src/main/java/org/apache/cassandra/sidecar/modules/CassandraOperationsModule.java
Outdated
Show resolved
Hide resolved
4b0287f to
c97daba
Compare
c97daba to
faa9f7c
Compare
fd5e624 to
a6b5497
Compare
arjunashok
left a comment
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.
Looking good for the most part. Added some minor comments.
client/src/main/java/org/apache/cassandra/sidecar/client/SidecarClient.java
Outdated
Show resolved
Hide resolved
| assertThat(stopResponse).isNotNull(); | ||
| assertThat(stopResponse.status()).isEqualTo(CompactionStopStatus.SUBMITTED); | ||
| assertThat(stopResponse.compactionType()).isEqualTo("COMPACTION"); | ||
| assertThat(stopResponse.reason()).isEqualTo("Operation Succeeded"); |
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 longer applicable, correct?
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.
Omitted the reason() field - the status , type, and id fields still stand in the response so left those in
...s/src/integrationTest/org/apache/cassandra/sidecar/routes/CompactionStopIntegrationTest.java
Outdated
Show resolved
Hide resolved
...s/src/integrationTest/org/apache/cassandra/sidecar/routes/CompactionStopIntegrationTest.java
Outdated
Show resolved
Hide resolved
5013920 to
def6e6f
Compare
def6e6f to
f404939
Compare
...in/java/org/apache/cassandra/sidecar/adapters/base/CassandraCompactionManagerOperations.java
Outdated
Show resolved
Hide resolved
| public static final String STREAM_STATS_ROUTE = API_V1 + CASSANDRA + "/stats/streams"; | ||
| public static final String TABLE_STATS_ROUTE = API_V1 + CASSANDRA + PER_KEYSPACE + PER_TABLE + "/stats"; | ||
|
|
||
| public static final String COMPACTION_STOP_ROUTE = API_V1 + CASSANDRA + "/operations/compaction/stop"; |
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: I see the operations part of the path in several static variables here. Let's extract it to its own private static
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.
Done. Added the private static, but only used it for the node stop route rather than node drain and node decommission routes which also uses this path, as those changes would not be directly related to this PR.
...main/java/org/apache/cassandra/sidecar/common/request/data/CompactionStopRequestPayload.java
Outdated
Show resolved
Hide resolved
|
|
||
| // Attempt to stop the compaction | ||
| // If compactionId is provided, use it (takes precedence over type) | ||
| if (compactionId != null && !compactionId.trim().isEmpty()) { |
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 this pattern of "if compactionID then do otherwise do by type" in several different places. What do you think about abstracting that inside operations, with a generic method that does stopCompaction(@Nullable String compactionId, @Nullable String compactionType), and performs that if internally?
Sorry if this has already been discussed.
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 in the latter case we would have a single method that accepts two params but only uses one, which others expressed was not preferable. Thus, preserved the stopByID() and stopCompaction() structure already used by node stop
|
|
||
| // Validate that at least one field is provided | ||
| if (payload.compactionType() == null && | ||
| (payload.compactionId() == null || payload.compactionId().trim().isEmpty())) |
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 also see this pattern of == null or == null or empty across different places. What about adding boolean public methods on payload that return if they are valid? Something like isCompactionTypeValid() and isCompactionIdValid?
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.
Done - added those functions in CompactionStopRequestPayload.java, although didn't use those functions for the pattern present in CassandraCompactionManagerOperations.java, as those methods don't work with the payload object.
Line 77 in 0a9b3f4
| public boolean hasValidCompactionId() { |
b7d1bae to
39c9242
Compare
...ava/org/apache/cassandra/sidecar/adapters/base/CassandraCompactionManagerOperationsTest.java
Outdated
Show resolved
Hide resolved
.../java/org/apache/cassandra/sidecar/common/request/data/CompactionStopRequestPayloadTest.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/apache/cassandra/sidecar/handlers/CompactionStopHandler.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/apache/cassandra/sidecar/handlers/CompactionStopHandler.java
Show resolved
Hide resolved
...in/java/org/apache/cassandra/sidecar/adapters/base/CassandraCompactionManagerOperations.java
Show resolved
Hide resolved
|
Looks good overall, few minor comments |
sarankk
left a comment
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.
+1 Thanks Shalni, overall looks great to me. Left some comments, I am +1 once the comments are addressed.
...in/java/org/apache/cassandra/sidecar/adapters/base/CassandraCompactionManagerOperations.java
Outdated
Show resolved
Hide resolved
...in/java/org/apache/cassandra/sidecar/adapters/base/CassandraCompactionManagerOperations.java
Outdated
Show resolved
Hide resolved
...in/java/org/apache/cassandra/sidecar/adapters/base/CassandraCompactionManagerOperations.java
Outdated
Show resolved
Hide resolved
...main/java/org/apache/cassandra/sidecar/adapters/base/jmx/CompactionManagerJmxOperations.java
Show resolved
Hide resolved
client-common/src/main/java/org/apache/cassandra/sidecar/common/ApiEndpointsV1.java
Outdated
Show resolved
Hide resolved
...on/src/main/java/org/apache/cassandra/sidecar/common/server/CompactionManagerOperations.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/apache/cassandra/sidecar/modules/CassandraOperationsModule.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/apache/cassandra/sidecar/modules/CassandraOperationsModule.java
Outdated
Show resolved
Hide resolved
| /** | ||
| * Supported compaction types based on Cassandra's OperationType enum | ||
| */ | ||
| public enum CompactionType |
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 do not see MAJOR_COMPACTION type here from OperationType class, is that intentional?
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 for the catch - I may have been looking at another C* version. Just changed it to reflect this list: https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/db/compaction/OperationType.java
client-common/src/main/java/org/apache/cassandra/sidecar/common/data/CompactionType.java
Outdated
Show resolved
Hide resolved
| @@ -0,0 +1,17 @@ | |||
| package org.apache.cassandra.sidecar.common.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.
Missing license for file
…ported compaction type per cassandra version
…rs to check for supported compaction type
Add bespoke API endpoint for nodetool compaction stop.
This implementation carries out functionality currently performed when execution command
nodetool stop, which is a short-running operation that requests ongoing compactions of a specifiedtypeoridto be stopped.See CASSANDRA-20021 JIRA ticket - more details can be found on ongoing effort to build APIs for nodetool C* cluster management operations.
patch by Shalni Sundram