From b9f5f7f743be6054088364fe136a63f975a0a99d Mon Sep 17 00:00:00 2001 From: Miles-Garnsey Date: Wed, 20 Sep 2023 14:54:15 +1000 Subject: [PATCH 1/4] Add new test for null statusChanges in the job response. --- .../mgmtapi/BaseDockerIntegrationTest.java | 1 + .../datastax/mgmtapi/NonDestructiveOpsIT.java | 41 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/management-api-server/src/test/java/com/datastax/mgmtapi/BaseDockerIntegrationTest.java b/management-api-server/src/test/java/com/datastax/mgmtapi/BaseDockerIntegrationTest.java index 70a7a9c9..030ed480 100644 --- a/management-api-server/src/test/java/com/datastax/mgmtapi/BaseDockerIntegrationTest.java +++ b/management-api-server/src/test/java/com/datastax/mgmtapi/BaseDockerIntegrationTest.java @@ -44,6 +44,7 @@ public abstract class BaseDockerIntegrationTest { protected static final String BASE_PATH = "http://localhost:8080/api/v0"; protected static final String BASE_PATH_V1 = "http://localhost:8080/api/v1"; protected static final String BASE_PATH_V2 = "http://localhost:8080/api/v2"; + protected static final String BASE_HOST = "http://localhost:8080"; protected static final URL BASE_URL; protected static final ObjectMapper JSON_MAPPER = new ObjectMapper(); diff --git a/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java b/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java index 0d86a627..0a51475f 100644 --- a/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java +++ b/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java @@ -5,6 +5,7 @@ */ package com.datastax.mgmtapi; +import static java.util.concurrent.TimeUnit.SECONDS; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.awaitility.Awaitility.await; @@ -17,6 +18,8 @@ import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; +import com.datastax.mgmtapi.client.api.DefaultApi; +import com.datastax.mgmtapi.client.invoker.ApiClient; import com.datastax.mgmtapi.helpers.IntegrationTestUtils; import com.datastax.mgmtapi.helpers.NettyHttpClient; import com.datastax.mgmtapi.resources.models.CompactRequest; @@ -49,7 +52,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.tuple.Pair; import org.apache.http.HttpStatus; import org.apache.http.client.utils.URIBuilder; @@ -112,7 +114,7 @@ public static void ensureStarted() throws IOException { if (ready) break; - Uninterruptibles.sleepUninterruptibly(10, TimeUnit.SECONDS); + Uninterruptibles.sleepUninterruptibly(10, SECONDS); } logger.info("CASSANDRA ALIVE: {}", ready); @@ -1033,4 +1035,39 @@ public void testMoveNode() throws IOException, URISyntaxException { "status", value -> assertThat(value).isIn("COMPLETED", "ERROR")); }); } + + public void ensureStatusChanges() throws Exception { + assumeTrue(IntegrationTestUtils.shouldRun()); + ensureStarted(); + NettyHttpClient client = new NettyHttpClient(BASE_URL); + DefaultApi apiClient = new DefaultApi(new ApiClient().setBasePath(BASE_HOST)); + com.datastax.mgmtapi.client.model.RepairRequest req = + new com.datastax.mgmtapi.client.model.RepairRequest() + .keyspace("system_distributed") + .fullRepair(true) + .notifications(true) + .repairParallelism( + com.datastax.mgmtapi.client.model.RepairRequest.RepairParallelismEnum.SEQUENTIAL) + .associatedTokens( + Collections.singletonList( + new com.datastax.mgmtapi.client.model.RingRange() + .start(Long.valueOf(-1)) + .end(Long.valueOf(100)))); + logger.info("Sending repair request: {}", req); + String jobID = apiClient.putRepairV2(req).getRepairId(); + Integer repairID = Integer.parseInt(jobID.substring(7)); // Trimming off "repair-" prefix. + logger.info("Repair ID: {}", repairID); + assertThat(repairID).isNotNull(); + assertThat(repairID).isGreaterThan(0); + + com.datastax.mgmtapi.client.model.Job status = apiClient.getJobStatus(jobID); + logger.info("Repair job status: {}", status); + assertThat(status.getStatus()).isNotNull(); + assertThat(status.getStatusChanges()).isNotNull(); + await().atMost(5, SECONDS).until(() -> status.getStatusChanges().size() > 0); + await() + .atMost(5, SECONDS) + .until( + () -> status.getStatus() == com.datastax.mgmtapi.client.model.Job.StatusEnum.COMPLETED); + } } From 16168480ef582f51164f26609bcf34bdf9df8ec8 Mon Sep 17 00:00:00 2001 From: Miles-Garnsey Date: Thu, 21 Sep 2023 13:07:29 +1000 Subject: [PATCH 2/4] Rewrite job status test to use direct HTTP calls and avoid using the client for build reasons. --- .../datastax/mgmtapi/NonDestructiveOpsIT.java | 73 ++++++++++++------- .../mgmtapi/helpers/NettyHttpClient.java | 30 ++++++++ 2 files changed, 78 insertions(+), 25 deletions(-) diff --git a/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java b/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java index 0a51475f..49ae05bf 100644 --- a/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java +++ b/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java @@ -18,8 +18,6 @@ import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; -import com.datastax.mgmtapi.client.api.DefaultApi; -import com.datastax.mgmtapi.client.invoker.ApiClient; import com.datastax.mgmtapi.helpers.IntegrationTestUtils; import com.datastax.mgmtapi.helpers.NettyHttpClient; import com.datastax.mgmtapi.resources.models.CompactRequest; @@ -34,6 +32,8 @@ import com.datastax.mgmtapi.resources.models.ScrubRequest; import com.datastax.mgmtapi.resources.models.Table; import com.datastax.mgmtapi.resources.models.TakeSnapshotRequest; +import com.datastax.mgmtapi.resources.v2.models.RepairParallelism; +import com.datastax.mgmtapi.resources.v2.models.RepairRequestResponse; import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; @@ -1036,38 +1036,61 @@ public void testMoveNode() throws IOException, URISyntaxException { }); } - public void ensureStatusChanges() throws Exception { + @Test + public void testEnsureStatusChanges() throws Exception { assumeTrue(IntegrationTestUtils.shouldRun()); ensureStarted(); NettyHttpClient client = new NettyHttpClient(BASE_URL); - DefaultApi apiClient = new DefaultApi(new ApiClient().setBasePath(BASE_HOST)); - com.datastax.mgmtapi.client.model.RepairRequest req = - new com.datastax.mgmtapi.client.model.RepairRequest() - .keyspace("system_distributed") - .fullRepair(true) - .notifications(true) - .repairParallelism( - com.datastax.mgmtapi.client.model.RepairRequest.RepairParallelismEnum.SEQUENTIAL) - .associatedTokens( - Collections.singletonList( - new com.datastax.mgmtapi.client.model.RingRange() - .start(Long.valueOf(-1)) - .end(Long.valueOf(100)))); + + com.datastax.mgmtapi.resources.v2.models.RepairRequest req = + new com.datastax.mgmtapi.resources.v2.models.RepairRequest( + "system_distributed", + null, + true, + true, + Collections.singletonList( + new com.datastax.mgmtapi.resources.v2.models.RingRange(-1L, 100L)), + RepairParallelism.SEQUENTIAL, + null, + null); + logger.info("Sending repair request: {}", req); - String jobID = apiClient.putRepairV2(req).getRepairId(); - Integer repairID = Integer.parseInt(jobID.substring(7)); // Trimming off "repair-" prefix. + URI repairUri = new URIBuilder(BASE_PATH_V2 + "repairs").build(); + Pair repairResp = + client + .put(repairUri.toURL(), new ObjectMapper().writeValueAsString(req)) + .thenApply(this::responseAsCodeAndBody) + .join(); + String jobID = + new ObjectMapper().readValue(repairResp.getRight(), RepairRequestResponse.class).repairID; + Integer repairID = + Integer.parseInt( + jobID.substring(7) // Trimming off "repair-" prefix. + ); logger.info("Repair ID: {}", repairID); assertThat(repairID).isNotNull(); assertThat(repairID).isGreaterThan(0); - com.datastax.mgmtapi.client.model.Job status = apiClient.getJobStatus(jobID); - logger.info("Repair job status: {}", status); - assertThat(status.getStatus()).isNotNull(); - assertThat(status.getStatusChanges()).isNotNull(); - await().atMost(5, SECONDS).until(() -> status.getStatusChanges().size() > 0); + URI statusUri = + new URIBuilder(BASE_PATH_V2 + "/ops/executor/job").addParameter("job_id", jobID).build(); + Pair statusResp = + client.get(statusUri.toURL()).thenApply(this::responseAsCodeAndBody).join(); + logger.info("Repair job status: {}", statusResp); + Job jobStatus = new ObjectMapper().readValue(statusResp.getRight(), Job.class); + + assertThat(jobStatus.getStatus()).isNotNull(); + assertThat(jobStatus.getStatusChanges()).isNotNull(); await() .atMost(5, SECONDS) .until( - () -> status.getStatus() == com.datastax.mgmtapi.client.model.Job.StatusEnum.COMPLETED); + () -> { + Pair statusResp2 = + client.get(statusUri.toURL()).thenApply(this::responseAsCodeAndBody).join(); + logger.info("Repair job status: {}", statusResp); + Job jobStatus2 = new ObjectMapper().readValue(statusResp.getRight(), Job.class); + return jobStatus2.getStatusChanges().size() > 0 + && jobStatus2.getStatus() + == com.datastax.mgmtapi.resources.models.Job.JobStatus.COMPLETED; + }); } -} +} \ No newline at end of file diff --git a/management-api-server/src/test/java/com/datastax/mgmtapi/helpers/NettyHttpClient.java b/management-api-server/src/test/java/com/datastax/mgmtapi/helpers/NettyHttpClient.java index c56d4f70..027f638e 100644 --- a/management-api-server/src/test/java/com/datastax/mgmtapi/helpers/NettyHttpClient.java +++ b/management-api-server/src/test/java/com/datastax/mgmtapi/helpers/NettyHttpClient.java @@ -157,6 +157,36 @@ public CompletableFuture post( return result; } + public CompletableFuture put( + URL url, final CharSequence body, String contentType) throws UnsupportedEncodingException { + CompletableFuture result = new CompletableFuture<>(); + + if (!activeRequestFuture.compareAndSet(null, result)) + throw new RuntimeException("outstanding request"); + + DefaultFullHttpRequest request = + new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, url.getFile()); + request.headers().set(HttpHeaders.Names.CONTENT_TYPE, contentType); + request.headers().set(HttpHeaderNames.HOST, url.getHost()); + + if (body != null) { + request.content().writeBytes(body.toString().getBytes(CharsetUtil.UTF_8.name())); + request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, request.content().readableBytes()); + } else { + request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, 0); + } + + // Send the HTTP request. + client.writeAndFlush(request); + + return result; + } + + public CompletableFuture put(URL url, final CharSequence body) + throws UnsupportedEncodingException { + return post(url, body, "application/json"); + } + public CompletableFuture delete(URL url) { return buildAndSendRequest(HttpMethod.DELETE, url); } From 0613d1cb0f2bfb6645c7f66ea5d75cc28315539f Mon Sep 17 00:00:00 2001 From: Miles-Garnsey Date: Thu, 21 Sep 2023 13:07:29 +1000 Subject: [PATCH 3/4] Rewrite job status test to use direct HTTP calls and avoid using the client for build reasons. --- .../datastax/mgmtapi/NonDestructiveOpsIT.java | 72 ++++++++++++------- .../mgmtapi/helpers/NettyHttpClient.java | 30 ++++++++ 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java b/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java index 0a51475f..ccb7feca 100644 --- a/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java +++ b/management-api-server/src/test/java/com/datastax/mgmtapi/NonDestructiveOpsIT.java @@ -18,8 +18,6 @@ import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; -import com.datastax.mgmtapi.client.api.DefaultApi; -import com.datastax.mgmtapi.client.invoker.ApiClient; import com.datastax.mgmtapi.helpers.IntegrationTestUtils; import com.datastax.mgmtapi.helpers.NettyHttpClient; import com.datastax.mgmtapi.resources.models.CompactRequest; @@ -34,6 +32,8 @@ import com.datastax.mgmtapi.resources.models.ScrubRequest; import com.datastax.mgmtapi.resources.models.Table; import com.datastax.mgmtapi.resources.models.TakeSnapshotRequest; +import com.datastax.mgmtapi.resources.v2.models.RepairParallelism; +import com.datastax.mgmtapi.resources.v2.models.RepairRequestResponse; import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; @@ -1036,38 +1036,62 @@ public void testMoveNode() throws IOException, URISyntaxException { }); } - public void ensureStatusChanges() throws Exception { + @Test + public void testEnsureStatusChanges() throws Exception { assumeTrue(IntegrationTestUtils.shouldRun()); ensureStarted(); NettyHttpClient client = new NettyHttpClient(BASE_URL); - DefaultApi apiClient = new DefaultApi(new ApiClient().setBasePath(BASE_HOST)); - com.datastax.mgmtapi.client.model.RepairRequest req = - new com.datastax.mgmtapi.client.model.RepairRequest() - .keyspace("system_distributed") - .fullRepair(true) - .notifications(true) - .repairParallelism( - com.datastax.mgmtapi.client.model.RepairRequest.RepairParallelismEnum.SEQUENTIAL) - .associatedTokens( - Collections.singletonList( - new com.datastax.mgmtapi.client.model.RingRange() - .start(Long.valueOf(-1)) - .end(Long.valueOf(100)))); + + com.datastax.mgmtapi.resources.v2.models.RepairRequest req = + new com.datastax.mgmtapi.resources.v2.models.RepairRequest( + "system_distributed", + null, + true, + true, + Collections.singletonList( + new com.datastax.mgmtapi.resources.v2.models.RingRange(-1L, 100L)), + RepairParallelism.SEQUENTIAL, + null, + null); + logger.info("Sending repair request: {}", req); - String jobID = apiClient.putRepairV2(req).getRepairId(); - Integer repairID = Integer.parseInt(jobID.substring(7)); // Trimming off "repair-" prefix. + URI repairUri = new URIBuilder(BASE_PATH_V2 + "/repairs").build(); + Pair repairResp = + client + .put(repairUri.toURL(), new ObjectMapper().writeValueAsString(req)) + .thenApply(this::responseAsCodeAndBody) + .join(); + System.out.println("repairResp was " + repairResp); + String jobID = + new ObjectMapper().readValue(repairResp.getRight(), RepairRequestResponse.class).repairID; + Integer repairID = + Integer.parseInt( + jobID.substring(7) // Trimming off "repair-" prefix. + ); logger.info("Repair ID: {}", repairID); assertThat(repairID).isNotNull(); assertThat(repairID).isGreaterThan(0); - com.datastax.mgmtapi.client.model.Job status = apiClient.getJobStatus(jobID); - logger.info("Repair job status: {}", status); - assertThat(status.getStatus()).isNotNull(); - assertThat(status.getStatusChanges()).isNotNull(); - await().atMost(5, SECONDS).until(() -> status.getStatusChanges().size() > 0); + URI statusUri = + new URIBuilder(BASE_PATH_V2 + "/ops/executor/job").addParameter("job_id", jobID).build(); + Pair statusResp = + client.get(statusUri.toURL()).thenApply(this::responseAsCodeAndBody).join(); + logger.info("Repair job status: {}", statusResp); + Job jobStatus = new ObjectMapper().readValue(statusResp.getRight(), Job.class); + + assertThat(jobStatus.getStatus()).isNotNull(); + assertThat(jobStatus.getStatusChanges()).isNotNull(); await() .atMost(5, SECONDS) .until( - () -> status.getStatus() == com.datastax.mgmtapi.client.model.Job.StatusEnum.COMPLETED); + () -> { + Pair statusResp2 = + client.get(statusUri.toURL()).thenApply(this::responseAsCodeAndBody).join(); + logger.info("Repair job status: {}", statusResp); + Job jobStatus2 = new ObjectMapper().readValue(statusResp.getRight(), Job.class); + return jobStatus2.getStatusChanges().size() > 0 + && jobStatus2.getStatus() + == com.datastax.mgmtapi.resources.models.Job.JobStatus.COMPLETED; + }); } } diff --git a/management-api-server/src/test/java/com/datastax/mgmtapi/helpers/NettyHttpClient.java b/management-api-server/src/test/java/com/datastax/mgmtapi/helpers/NettyHttpClient.java index c56d4f70..027f638e 100644 --- a/management-api-server/src/test/java/com/datastax/mgmtapi/helpers/NettyHttpClient.java +++ b/management-api-server/src/test/java/com/datastax/mgmtapi/helpers/NettyHttpClient.java @@ -157,6 +157,36 @@ public CompletableFuture post( return result; } + public CompletableFuture put( + URL url, final CharSequence body, String contentType) throws UnsupportedEncodingException { + CompletableFuture result = new CompletableFuture<>(); + + if (!activeRequestFuture.compareAndSet(null, result)) + throw new RuntimeException("outstanding request"); + + DefaultFullHttpRequest request = + new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, url.getFile()); + request.headers().set(HttpHeaders.Names.CONTENT_TYPE, contentType); + request.headers().set(HttpHeaderNames.HOST, url.getHost()); + + if (body != null) { + request.content().writeBytes(body.toString().getBytes(CharsetUtil.UTF_8.name())); + request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, request.content().readableBytes()); + } else { + request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, 0); + } + + // Send the HTTP request. + client.writeAndFlush(request); + + return result; + } + + public CompletableFuture put(URL url, final CharSequence body) + throws UnsupportedEncodingException { + return post(url, body, "application/json"); + } + public CompletableFuture delete(URL url) { return buildAndSendRequest(HttpMethod.DELETE, url); } From 059d4b5191111d136f9f9cf55a6298181a5ff858 Mon Sep 17 00:00:00 2001 From: Miles-Garnsey Date: Thu, 21 Sep 2023 18:33:03 +1000 Subject: [PATCH 4/4] Try using a JobDTO which doesn't have an enum to avoid serialisation issues in RPC framework. --- .../com/datastax/mgmtapi/NodeOpsProvider.java | 30 +++-- .../java/com/datastax/mgmtapi/util/Job.java | 22 ++-- .../com/datastax/mgmtapi/util/JobDto.java | 111 ++++++++++++++++++ 3 files changed, 141 insertions(+), 22 deletions(-) create mode 100644 management-api-agent-common/src/main/java/com/datastax/mgmtapi/util/JobDto.java diff --git a/management-api-agent-common/src/main/java/com/datastax/mgmtapi/NodeOpsProvider.java b/management-api-agent-common/src/main/java/com/datastax/mgmtapi/NodeOpsProvider.java index eb74e3e9..ebb9712d 100644 --- a/management-api-agent-common/src/main/java/com/datastax/mgmtapi/NodeOpsProvider.java +++ b/management-api-agent-common/src/main/java/com/datastax/mgmtapi/NodeOpsProvider.java @@ -9,6 +9,7 @@ import com.datastax.mgmtapi.rpc.RpcParam; import com.datastax.mgmtapi.rpc.RpcRegistry; import com.datastax.mgmtapi.util.Job; +import com.datastax.mgmtapi.util.JobDto; import com.datastax.mgmtapi.util.JobExecutor; import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; @@ -79,22 +80,29 @@ public synchronized void unregister() { } @Rpc(name = "jobStatus") - public Map getJobStatus(@RpcParam(name = "job_id") String jobId) { - Map resultMap = new HashMap<>(); + public JobDto getJobStatus(@RpcParam(name = "job_id") String jobId) { Job jobWithId = service.getJobWithId(jobId); if (jobWithId == null) { - return resultMap; - } - resultMap.put("id", jobWithId.getJobId()); - resultMap.put("type", jobWithId.getJobType()); - resultMap.put("status", jobWithId.getStatus().name()); - resultMap.put("submit_time", String.valueOf(jobWithId.getSubmitTime())); - resultMap.put("end_time", String.valueOf(jobWithId.getFinishedTime())); + return new JobDto(null, null); + } + JobDto jobStatus = new JobDto(jobWithId.getJobType(), jobWithId.getJobId()); + jobStatus.setStatus(jobWithId.getStatus().name()); + jobWithId.statusChanges.stream() + .forEach( + statusChange -> { + JobDto.StatusChange changeToAdd = + jobStatus.new StatusChange(statusChange.getStatus(), statusChange.message); + changeToAdd.changeTime = statusChange.getChangeTime(); + jobStatus.statusChanges.add(changeToAdd); + }); + jobStatus.submitTime = jobWithId.getSubmitTime(); + jobStatus.finishedTime = jobWithId.getFinishedTime(); + jobStatus.startTime = jobWithId.startTime; if (jobWithId.getStatus() == Job.JobStatus.ERROR) { - resultMap.put("error", jobWithId.getError().getLocalizedMessage()); + jobStatus.setError(jobWithId.getError()); } - return resultMap; + return jobStatus; } @Rpc(name = "setFullQuerylog") diff --git a/management-api-agent-common/src/main/java/com/datastax/mgmtapi/util/Job.java b/management-api-agent-common/src/main/java/com/datastax/mgmtapi/util/Job.java index 20e4e9dd..a4726455 100644 --- a/management-api-agent-common/src/main/java/com/datastax/mgmtapi/util/Job.java +++ b/management-api-agent-common/src/main/java/com/datastax/mgmtapi/util/Job.java @@ -17,19 +17,19 @@ public enum JobStatus { WAITING; } - private String jobId; - private String jobType; - private JobStatus status; - private long submitTime; - private long startTime; - private long finishedTime; - private Throwable error; + public String jobId; + public String jobType; + public JobStatus status; + public long submitTime; + public long startTime; + public long finishedTime; + public Throwable error; public class StatusChange { - ProgressEventType status; - long changeTime; + public ProgressEventType status; + public long changeTime; - String message; + public String message; public StatusChange(ProgressEventType type, String message) { changeTime = System.currentTimeMillis(); @@ -50,7 +50,7 @@ public String getMessage() { } } - private List statusChanges; + public List statusChanges; public Job(String jobType, String jobId) { this.jobType = jobType; diff --git a/management-api-agent-common/src/main/java/com/datastax/mgmtapi/util/JobDto.java b/management-api-agent-common/src/main/java/com/datastax/mgmtapi/util/JobDto.java new file mode 100644 index 00000000..7c545a6c --- /dev/null +++ b/management-api-agent-common/src/main/java/com/datastax/mgmtapi/util/JobDto.java @@ -0,0 +1,111 @@ +/* + * Copyright DataStax, Inc. + * + * Please see the included license file for details. + */ +package com.datastax.mgmtapi.util; + +import com.google.common.annotations.VisibleForTesting; +import java.util.ArrayList; +import java.util.List; +import org.apache.cassandra.utils.progress.ProgressEventType; + +public class JobDto { + + public String jobId; + public String jobType; + public String status; + public long submitTime; + public long startTime; + public long finishedTime; + public Throwable error; + + public class StatusChange { + public ProgressEventType status; + public long changeTime; + + public String message; + + public StatusChange(ProgressEventType type, String message) { + changeTime = System.currentTimeMillis(); + status = type; + this.message = message; + } + + public ProgressEventType getStatus() { + return status; + } + + public long getChangeTime() { + return changeTime; + } + + public String getMessage() { + return message; + } + } + + public List statusChanges; + + public JobDto(String jobType, String jobId) { + this.jobType = jobType; + this.jobId = jobId; + submitTime = System.currentTimeMillis(); + status = "WAITING"; + statusChanges = new ArrayList<>(); + } + + @VisibleForTesting + // This method is only for testing purposes + public void setJobId(String jobId) { + this.jobId = jobId; + } + + public String getJobId() { + return jobId; + } + + public String getJobType() { + return jobType; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public void setStatusChange(ProgressEventType type, String message) { + statusChanges.add(new StatusChange(type, message)); + } + + public List getStatusChanges() { + return statusChanges; + } + + public long getSubmitTime() { + return submitTime; + } + + public long getFinishedTime() { + return finishedTime; + } + + public void setFinishedTime(long finishedTime) { + this.finishedTime = finishedTime; + } + + public Throwable getError() { + return error; + } + + public void setError(Throwable error) { + this.error = error; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } +}