From ecff674b0b354a6aad3a91244aa029736e19d8b7 Mon Sep 17 00:00:00 2001 From: Siarhei Hrabko <45555481+grabsefx@users.noreply.github.com> Date: Mon, 15 Apr 2024 09:02:45 +0300 Subject: [PATCH] EPMRPP-88602 Prepare models for supporting microsecons/nanosecond format (#2) * EPMRPP-88602 || Migrate dates to Instant type || Implement date deserializer || Introduce junit 5 || Add lombok suppoprt --------- Co-authored-by: Pavel Bortnik Co-authored-by: PeeAyBee (cherry picked from commit b5769dc3bd5ae1837681ddc8574159aea1ed4d5d) --- build.gradle | 14 +- gradle.properties | 4 +- .../ws/reporting/FinishExecutionRQ.java | 55 +--- .../ws/reporting/FinishTestItemRQ.java | 57 +--- .../ta/reportportal/ws/reporting/Issue.java | 147 ++--------- .../ws/reporting/LaunchResource.java | 180 ++----------- .../ws/reporting/MergeLaunchesRQ.java | 153 +---------- .../reportportal/ws/reporting/SaveLogRQ.java | 115 +------- .../ta/reportportal/ws/reporting/StartRQ.java | 94 +------ .../ws/reporting/TestItemResource.java | 245 +----------------- .../databind/MultiFormatDateDeserializer.java | 74 ++++++ .../MultiFormatDateDeserializerTest.java | 72 +++++ 12 files changed, 264 insertions(+), 946 deletions(-) create mode 100644 src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java create mode 100644 src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java diff --git a/build.gradle b/build.gradle index 00e70b3..414419c 100644 --- a/build.gradle +++ b/build.gradle @@ -46,13 +46,21 @@ dependencies { implementation "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}" implementation "javax.validation:validation-api:${validationApiVersion}" implementation "org.apache.commons:commons-lang3:${commonsLangVersion}" - implementation group: 'com.google.guava', name: 'guava', version: '28.2-jre' testImplementation "junit:junit:${junitVersion}" + testImplementation "org.junit.jupiter:junit-jupiter-api:${jupiterVersion}" + testImplementation "org.junit.jupiter:junit-jupiter-params:${jupiterVersion}" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${jupiterVersion}" testImplementation "org.mockito:mockito-junit-jupiter:${mockitoJunitJupiter}" testImplementation "org.hibernate.validator:hibernate-validator:${hibernateValidatorVersion}" testImplementation "javax.el:javax.el-api:${elApiVersion}" testImplementation "org.glassfish:javax.el:${elApiVersion}" + + // add lombok support + compileOnly "org.projectlombok:lombok:${lombokVersion}" + annotationProcessor "org.projectlombok:lombok:${lombokVersion}" + testCompileOnly "org.projectlombok:lombok:${lombokVersion}" + testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}" } dependencyCheck { @@ -60,4 +68,6 @@ dependencies { } } - +test { + useJUnitPlatform() +} diff --git a/gradle.properties b/gradle.properties index 82384ec..7678132 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,8 +3,10 @@ description=EPAM Report portal. REST Reporting API model hibernateValidatorVersion=6.1.2.Final validationApiVersion=2.0.1.Final junitVersion=4.12 +jupiterVersion=5.8.1 elApiVersion=3.0.0 sprindocAnnotationsVersion=1.7.0 commonsLangVersion=3.9 -mockitoJunitJupiter=2.23.0 +mockitoJunitJupiter=3.4.6 jacksonVersion=2.10.2 +lombokVersion=1.18.30 diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/FinishExecutionRQ.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/FinishExecutionRQ.java index 4dad008..74ee41b 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/FinishExecutionRQ.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/FinishExecutionRQ.java @@ -19,17 +19,22 @@ import static com.epam.ta.reportportal.ws.reporting.ValidationConstraints.MAX_PARAMETERS_LENGTH; import com.epam.ta.reportportal.ws.annotations.In; +import com.epam.ta.reportportal.ws.reporting.databind.MultiFormatDateDeserializer; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import java.util.Date; +import java.time.Instant; import java.util.Set; import javax.validation.Valid; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; /** * Finishes some entity execution in Report Portal
May be Launch, TestSuite, Test, TestStep @@ -37,13 +42,17 @@ * @author Andrei Varabyeu */ @JsonInclude(Include.NON_NULL) +@Getter +@Setter +@ToString public class FinishExecutionRQ { @NotNull @JsonProperty(value = "endTime", required = true) @JsonAlias({"endTime", "end_time"}) @Schema(requiredMode = RequiredMode.REQUIRED) - private Date endTime; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant endTime; @JsonProperty(value = "status") @In(allowedValues = {"passed", "failed", "stopped", "skipped", "interrupted", "cancelled", "info", @@ -60,44 +69,4 @@ public class FinishExecutionRQ { @JsonAlias({"attributes", "tags"}) private Set attributes; - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Set getAttributes() { - return attributes; - } - - public void setAttributes(Set attributes) { - this.attributes = attributes; - } - - public Date getEndTime() { - return endTime; - } - - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - @Override - public String toString() { - return "FinishExecutionRQ{" + "endTime=" + endTime - + ", status='" + status + '\'' - + ", description='" + description + '\'' - + ", attributes=" + attributes - + '}'; - } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/FinishTestItemRQ.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/FinishTestItemRQ.java index a0303c1..2f2fb8b 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/FinishTestItemRQ.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/FinishTestItemRQ.java @@ -22,8 +22,14 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import javax.validation.Valid; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; @JsonInclude(Include.NON_NULL) +@Getter +@Setter +@ToString public class FinishTestItemRQ extends FinishExecutionRQ { @Valid @@ -43,53 +49,4 @@ public class FinishTestItemRQ extends FinishExecutionRQ { @JsonProperty(value = "retryOf") private String retryOf; - public Boolean isRetry() { - return retry; - } - - public void setRetry(Boolean retry) { - this.retry = retry; - } - - public Issue getIssue() { - return issue; - } - - public void setIssue(Issue issue) { - this.issue = issue; - } - - public String getLaunchUuid() { - return launchUuid; - } - - public void setLaunchUuid(String launchUuid) { - this.launchUuid = launchUuid; - } - - public String getTestCaseId() { - return testCaseId; - } - - public void setTestCaseId(String testCaseId) { - this.testCaseId = testCaseId; - } - - public String getRetryOf() { - return retryOf; - } - - public void setRetryOf(String retryOf) { - this.retryOf = retryOf; - } - - @Override - public String toString() { - return "FinishTestItemRQ{" + "issue=" + issue - + ", retry=" + retry - + ", launchUuid='" + launchUuid + '\'' - + ", testCaseId='" + testCaseId + '\'' - + ", retryOf='" + retryOf + '\'' - + '}'; - } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/Issue.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/Issue.java index 0e3e38e..8aa1e47 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/Issue.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/Issue.java @@ -16,15 +16,23 @@ package com.epam.ta.reportportal.ws.reporting; +import com.epam.ta.reportportal.ws.reporting.databind.MultiFormatDateDeserializer; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Objects; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.time.Instant; import java.util.Set; import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; /** * Test item issue @@ -32,6 +40,8 @@ * @author Dzianis Shlychkou */ @JsonInclude(Include.NON_NULL) +@Data +@NoArgsConstructor public class Issue { @NotBlank @@ -55,6 +65,10 @@ public class Issue { private Set externalSystemIssues; @JsonInclude(Include.NON_NULL) + @Getter + @Setter + @EqualsAndHashCode + @ToString public static class ExternalSystemIssue { @NotBlank @@ -62,7 +76,8 @@ public static class ExternalSystemIssue { private String ticketId; @JsonProperty(value = "submitDate") - private Long submitDate; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant submitDate; @NotBlank @JsonProperty(value = "btsUrl") @@ -79,132 +94,6 @@ public static class ExternalSystemIssue { @JsonProperty(value = "pluginName") private String pluginName; - public void setTicketId(String ticketId) { - this.ticketId = ticketId; - } - - public String getTicketId() { - return ticketId; - } - - public Long getSubmitDate() { - return submitDate; - } - - public void setSubmitDate(Long submitDate) { - this.submitDate = submitDate; - } - - public String getBtsUrl() { - return btsUrl; - } - - public void setBtsUrl(String btsUrl) { - this.btsUrl = btsUrl; - } - - public String getBtsProject() { - return btsProject; - } - - public void setBtsProject(String btsProject) { - this.btsProject = btsProject; - } - - public void setUrl(String value) { - this.url = value; - } - - public String getUrl() { - return url; - } - - public String getPluginName() { - return pluginName; - } - - public void setPluginName(String pluginName) { - this.pluginName = pluginName; - } - - @Override - public String toString() { - return "ExternalSystemIssue{" + "ticketId='" + ticketId + '\'' + ", submitDate=" + submitDate - + ", btsUrl='" + btsUrl + '\'' - + ", btsProject='" + btsProject + '\'' + ", url='" + url + '\'' + ", pluginName='" - + pluginName + '\'' + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ExternalSystemIssue that = (ExternalSystemIssue) o; - return Objects.equals(ticketId, that.ticketId) && Objects.equals(submitDate, that.submitDate) - && Objects.equals(btsUrl, - that.btsUrl - ) && Objects.equals(btsProject, that.btsProject) && Objects.equals(url, that.url) - && Objects.equals(pluginName, - that.pluginName - ); - } - - @Override - public int hashCode() { - return Objects.hash(ticketId, submitDate, btsUrl, btsProject, url, pluginName); - } } - public void setExternalSystemIssues(Set externalSystemIssues) { - this.externalSystemIssues = externalSystemIssues; - } - - public Set getExternalSystemIssues() { - return externalSystemIssues; - } - - public String getIssueType() { - return issueType; - } - - public void setIssueType(String issueType) { - this.issueType = issueType; - } - - public String getComment() { - return comment; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public boolean getAutoAnalyzed() { - return autoAnalyzed; - } - - public void setAutoAnalyzed(boolean autoAnalyzed) { - this.autoAnalyzed = autoAnalyzed; - } - - public boolean getIgnoreAnalyzer() { - return ignoreAnalyzer; - } - - public void setIgnoreAnalyzer(boolean ignoreAnalyzer) { - this.ignoreAnalyzer = ignoreAnalyzer; - } - - @Override - public String toString() { - return "Issue{" + "issueType='" + issueType + '\'' - + ", comment='" + comment + '\'' - + ", autoAnalyzed='" + autoAnalyzed + "'" - + ", externalSystemIssues=" + externalSystemIssues - + '}'; - } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/LaunchResource.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/LaunchResource.java index 99002d7..4118e51 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/LaunchResource.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/LaunchResource.java @@ -16,10 +16,12 @@ package com.epam.ta.reportportal.ws.reporting; +import com.epam.ta.reportportal.ws.reporting.databind.MultiFormatDateDeserializer; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Date; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.time.Instant; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; @@ -27,6 +29,9 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; /** * JSON Representation of Report Portal's Launch domain object @@ -34,6 +39,9 @@ * @author Andrei Varabyeu */ @JsonInclude(Include.NON_NULL) +@Getter +@Setter +@ToString public class LaunchResource extends OwnedResource { @NotNull @@ -59,13 +67,16 @@ public class LaunchResource extends OwnedResource { @NotNull @JsonProperty(value = "startTime", required = true) - private Date startTime; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant startTime; @JsonProperty(value = "endTime") - private Date endTime; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant endTime; @JsonProperty(value = "lastModified") - private Date lastModified; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant lastModified; @NotNull @JsonProperty(value = "status", required = true) @@ -96,165 +107,4 @@ public class LaunchResource extends OwnedResource { @JsonProperty(value = "metadata") private Map metadata; - public double getApproximateDuration() { - return approximateDuration; - } - - public void setApproximateDuration(double approximateDuration) { - this.approximateDuration = approximateDuration; - } - - public Long getLaunchId() { - return launchId; - } - - public void setLaunchId(Long launchId) { - this.launchId = launchId; - } - - public String getUuid() { - return uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Long getNumber() { - return number; - } - - public void setNumber(Long number) { - this.number = number; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Date getStartTime() { - return startTime; - } - - public void setStartTime(Date startTime) { - this.startTime = startTime; - } - - public Date getEndTime() { - return endTime; - } - - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - - public Date getLastModified() { - return lastModified; - } - - public void setLastModified(Date lastModified) { - this.lastModified = lastModified; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public StatisticsResource getStatisticsResource() { - return statisticsResource; - } - - public void setStatisticsResource(StatisticsResource statisticsResource) { - this.statisticsResource = statisticsResource; - } - - public Set getAttributes() { - return attributes; - } - - public void setAttributes(Set attributes) { - this.attributes = attributes; - } - - public Mode getMode() { - return mode; - } - - public void setMode(Mode mode) { - this.mode = mode; - } - - public Set getAnalyzers() { - return analyzers; - } - - public void setAnalyzers(Set analyzers) { - this.analyzers = analyzers; - } - - public boolean isHasRetries() { - return hasRetries; - } - - public boolean getHasRetries() { - return hasRetries; - } - - public void setHasRetries(boolean hasRetries) { - this.hasRetries = hasRetries; - } - - public boolean isRerun() { - return rerun; - } - - public void setRerun(boolean rerun) { - this.rerun = rerun; - } - - public Map getMetadata() { - return metadata; - } - - public void setMetadata(Map metadata) { - this.metadata = metadata; - } - - @Override - public String toString() { - return "LaunchResource{" + "launchId=" + launchId - + ", uuid='" + uuid + '\'' - + ", name='" + name + '\'' - + ", number=" + number - + ", description='" + description + '\'' - + ", startTime=" + startTime - + ", endTime=" + endTime - + ", lastModified=" + lastModified - + ", status='" + status + '\'' - + ", statisticsResource=" + statisticsResource - + ", attributes=" + attributes - + ", mode=" + mode - + ", analyzers=" + analyzers - + ", approximateDuration=" + approximateDuration - + ", hasRetries=" + hasRetries - + ", rerun=" + rerun - + ", metadata=" + metadata - + '}'; - } } diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/MergeLaunchesRQ.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/MergeLaunchesRQ.java index 50593f9..59beb6c 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/MergeLaunchesRQ.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/MergeLaunchesRQ.java @@ -20,19 +20,27 @@ import static com.epam.ta.reportportal.ws.reporting.ValidationConstraints.MAX_PARAMETERS_LENGTH; import com.epam.ta.reportportal.ws.annotations.NotBlankWithSize; +import com.epam.ta.reportportal.ws.reporting.databind.MultiFormatDateDeserializer; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import java.util.Date; +import java.time.Instant; import java.util.Set; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; @JsonInclude(Include.NON_NULL) +@Getter +@Setter +@ToString public class MergeLaunchesRQ { @NotBlankWithSize(min = ValidationConstraints.MIN_LAUNCH_NAME_LENGTH, max = ValidationConstraints.MAX_NAME_LENGTH) @@ -50,7 +58,8 @@ public class MergeLaunchesRQ { @JsonProperty(value = "startTime") @Schema - private Date startTime; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant startTime; @JsonProperty("mode") private Mode mode; @@ -62,7 +71,8 @@ public class MergeLaunchesRQ { @JsonProperty(value = "endTime") @Schema - private Date endTime; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant endTime; @NotNull @JsonProperty("mergeType") @@ -72,139 +82,4 @@ public class MergeLaunchesRQ { @JsonProperty(value = "extendSuitesDescription", required = true) private boolean extendSuitesDescription; - public String getName() { - return name; - } - - public void setName(@NotNull String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Set getAttributes() { - return attributes; - } - - public void setAttributes(Set attributes) { - this.attributes = attributes; - } - - public Date getStartTime() { - return startTime; - } - - public void setStartTime(Date startTime) { - this.startTime = startTime; - } - - public Mode getMode() { - return mode; - } - - public void setMode(Mode mode) { - this.mode = mode; - } - - @NotNull - public Set getLaunches() { - return launches; - } - - public void setLaunches(@NotNull Set launches) { - this.launches = launches; - } - - public Date getEndTime() { - return endTime; - } - - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - - @NotNull - public String getMergeStrategyType() { - return mergeStrategyType; - } - - public void setMergeStrategyType(@NotNull String mergeStrategyType) { - this.mergeStrategyType = mergeStrategyType; - } - - public boolean isExtendSuitesDescription() { - return extendSuitesDescription; - } - - public void setExtendSuitesDescription(boolean extendSuitesDescription) { - this.extendSuitesDescription = extendSuitesDescription; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - MergeLaunchesRQ that = (MergeLaunchesRQ) o; - - if (extendSuitesDescription != that.extendSuitesDescription) { - return false; - } - if (!name.equals(that.name)) { - return false; - } - if (description != null ? !description.equals(that.description) : that.description != null) { - return false; - } - if (attributes != null ? !attributes.equals(that.attributes) : that.attributes != null) { - return false; - } - if (startTime != null ? !startTime.equals(that.startTime) : that.startTime != null) { - return false; - } - if (mode != that.mode) { - return false; - } - if (!launches.equals(that.launches)) { - return false; - } - if (endTime != null ? !endTime.equals(that.endTime) : that.endTime != null) { - return false; - } - return mergeStrategyType.equals(that.mergeStrategyType); - } - - @Override - public int hashCode() { - int result = name.hashCode(); - result = 31 * result + (description != null ? description.hashCode() : 0); - result = 31 * result + (attributes != null ? attributes.hashCode() : 0); - result = 31 * result + (startTime != null ? startTime.hashCode() : 0); - result = 31 * result + (mode != null ? mode.hashCode() : 0); - result = 31 * result + launches.hashCode(); - result = 31 * result + (endTime != null ? endTime.hashCode() : 0); - result = 31 * result + mergeStrategyType.hashCode(); - result = 31 * result + (extendSuitesDescription ? 1 : 0); - return result; - } - - @Override - public String toString() { - return "MergeLaunchesRQ{" + "name='" + name + '\'' + ", description='" + description + '\'' - + ", attributes=" + attributes - + ", startTime=" + startTime + ", mode=" + mode + ", launches=" + launches + ", endTime=" - + endTime - + ", mergeStrategyType='" + mergeStrategyType + '\'' + ", extendSuitesDescription=" - + extendSuitesDescription + '}'; - } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/SaveLogRQ.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/SaveLogRQ.java index 690ad01..8d0f9dc 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/SaveLogRQ.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/SaveLogRQ.java @@ -16,22 +16,29 @@ package com.epam.ta.reportportal.ws.reporting; +import com.epam.ta.reportportal.ws.reporting.databind.MultiFormatDateDeserializer; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import java.util.Arrays; -import java.util.Date; +import java.time.Instant; import javax.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; /** * @author Henadzi_Vrubleuski * @author Andrei Varabyeu */ @JsonInclude(Include.NON_NULL) +@Getter +@Setter +@ToString public class SaveLogRQ { @JsonProperty("uuid") @@ -48,7 +55,8 @@ public class SaveLogRQ { @NotNull @JsonProperty(value = "time", required = true) @Schema(requiredMode = RequiredMode.REQUIRED) - private Date logTime; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant logTime; @JsonProperty(value = "message") private String message; @@ -60,63 +68,10 @@ public class SaveLogRQ { @JsonProperty(value = "file") private File file; - public String getUuid() { - return uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public Date getLogTime() { - return logTime; - } - - public void setLogTime(Date logTime) { - this.logTime = logTime; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public String getItemUuid() { - return itemUuid; - } - - public void setItemUuid(String itemUuid) { - this.itemUuid = itemUuid; - } - - public String getLaunchUuid() { - return launchUuid; - } - - public void setLaunchUuid(String launchUuid) { - this.launchUuid = launchUuid; - } - - public void setLevel(String level) { - this.level = level; - } - - public String getLevel() { - return level; - } - - public void setFile(File file) { - this.file = file; - } - - public File getFile() { - return file; - } - @JsonInclude(Include.NON_NULL) + @Getter + @Setter + @ToString public static class File { @JsonProperty(value = "name") @@ -128,48 +83,6 @@ public static class File { @JsonIgnore private String contentType; - public void setName(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public byte[] getContent() { - return content; - } - - public void setContent(byte[] content) { - this.content = content; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - @Override - public String toString() { - return "File{" + "name='" + name + '\'' - + ", content=" + Arrays.toString(content) - + ", contentType='" + contentType + '\'' - + '}'; - } } - @Override - public String toString() { - return "SaveLogRQ{" + "uuid='" + uuid + '\'' - + ", itemUuid='" + itemUuid + '\'' - + ", launchUuid='" + launchUuid + '\'' - + ", logTime=" + logTime - + ", message='" + message + '\'' - + ", level='" + level + '\'' - + ", file=" + file - + '}'; - } } diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/StartRQ.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/StartRQ.java index 7829ab4..db39046 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/StartRQ.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/StartRQ.java @@ -18,17 +18,21 @@ import static com.epam.ta.reportportal.ws.reporting.ValidationConstraints.MAX_PARAMETERS_LENGTH; +import com.epam.ta.reportportal.ws.reporting.databind.MultiFormatDateDeserializer; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import java.util.Date; +import java.time.Instant; import java.util.Set; import javax.validation.Valid; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import lombok.Data; +import lombok.EqualsAndHashCode; /** * Base entity for start requests @@ -36,6 +40,7 @@ * @author Andrei Varabyeu */ @JsonInclude(Include.NON_NULL) +@Data public class StartRQ { @JsonProperty(value = "name", required = true) @@ -55,91 +60,12 @@ public class StartRQ { @JsonProperty(required = true) @JsonAlias({"startTime", "start_time"}) @Schema(requiredMode = RequiredMode.REQUIRED) - private Date startTime; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant startTime; @Schema(requiredMode = RequiredMode.REQUIRED) @JsonProperty(value = "uuid") + @EqualsAndHashCode.Exclude private String uuid; - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Set getAttributes() { - return attributes; - } - - public void setAttributes(Set attributes) { - this.attributes = attributes; - } - - public String getUuid() { - return uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public Date getStartTime() { - return startTime; - } - - public void setStartTime(Date startTime) { - this.startTime = startTime; - } - - @Override - public String toString() { - return "StartRQ{" + "name='" + name + '\'' - + ", description='" + description + '\'' - + ", attributes=" + attributes - + ", startTime=" + startTime - + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - StartRQ startRQ = (StartRQ) o; - - if (name != null ? !name.equals(startRQ.name) : startRQ.name != null) { - return false; - } - if (description != null ? !description.equals(startRQ.description) - : startRQ.description != null) { - return false; - } - if (attributes != null ? !attributes.equals(startRQ.attributes) : startRQ.attributes != null) { - return false; - } - return startTime != null ? startTime.equals(startRQ.startTime) : startRQ.startTime == null; - } - - @Override - public int hashCode() { - int result = name != null ? name.hashCode() : 0; - result = 31 * result + (description != null ? description.hashCode() : 0); - result = 31 * result + (attributes != null ? attributes.hashCode() : 0); - result = 31 * result + (startTime != null ? startTime.hashCode() : 0); - return result; - } -} \ No newline at end of file +} diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/TestItemResource.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/TestItemResource.java index fe8c153..b21670e 100644 --- a/src/main/java/com/epam/ta/reportportal/ws/reporting/TestItemResource.java +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/TestItemResource.java @@ -16,12 +16,17 @@ package com.epam.ta.reportportal.ws.reporting; +import com.epam.ta.reportportal.ws.reporting.databind.MultiFormatDateDeserializer; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Date; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import java.time.Instant; import java.util.List; import java.util.Set; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; /** * JSON Representation of Report Portal domain object @@ -29,6 +34,9 @@ * @author Andrei Varabyeu */ @JsonInclude(Include.NON_NULL) +@Getter +@Setter +@ToString public class TestItemResource { @JsonProperty(value = "id") @@ -56,10 +64,12 @@ public class TestItemResource { private String type; @JsonProperty(value = "startTime") - private Date startTime; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant startTime; @JsonProperty(value = "endTime") - private Date endTime; + @JsonDeserialize(using = MultiFormatDateDeserializer.class) + private Instant endTime; @JsonProperty(value = "status") private String status; @@ -106,233 +116,4 @@ public class TestItemResource { @JsonProperty(value = "path") private String path; - public List getRetries() { - return retries; - } - - public void setRetries(List retries) { - this.retries = retries; - } - - public Long getLaunchId() { - return launchId; - } - - public void setLaunchId(Long launchId) { - this.launchId = launchId; - } - - public String getUuid() { - return uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public Long getItemId() { - return itemId; - } - - public void setItemId(Long itemId) { - this.itemId = itemId; - } - - public Issue getIssue() { - return issue; - } - - public void setIssue(Issue issue) { - this.issue = issue; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getCodeRef() { - return codeRef; - } - - public void setCodeRef(String codeRef) { - this.codeRef = codeRef; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public List getParameters() { - return parameters; - } - - public void setParameters(List parameters) { - this.parameters = parameters; - } - - public Set getAttributes() { - return attributes; - } - - public void setAttributes(Set attributes) { - this.attributes = attributes; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public Date getStartTime() { - return startTime; - } - - public void setStartTime(Date startTime) { - this.startTime = startTime; - } - - public Date getEndTime() { - return endTime; - } - - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public Long getParent() { - return parent; - } - - public void setParent(Long parent) { - this.parent = parent; - } - - public PathNameResource getPathNames() { - return pathNames; - } - - public void setPathNames(PathNameResource pathNames) { - this.pathNames = pathNames; - } - - public String getLaunchStatus() { - return launchStatus; - } - - public void setLaunchStatus(String value) { - this.launchStatus = value; - } - - public StatisticsResource getStatisticsResource() { - return statisticsResource; - } - - public void setStatisticsResource(StatisticsResource statisticsResource) { - this.statisticsResource = statisticsResource; - } - - public boolean isHasChildren() { - return hasChildren; - } - - public void setHasChildren(boolean hasChildren) { - this.hasChildren = hasChildren; - } - - public boolean isHasStats() { - return hasStats; - } - - public void setHasStats(boolean hasStats) { - this.hasStats = hasStats; - } - - public String getUniqueId() { - return uniqueId; - } - - public void setUniqueId(String uniqueId) { - this.uniqueId = uniqueId; - } - - public String getTestCaseId() { - return testCaseId; - } - - public void setTestCaseId(String testCaseId) { - this.testCaseId = testCaseId; - } - - public Integer getTestCaseHash() { - return testCaseHash; - } - - public void setTestCaseHash(Integer testCaseHash) { - this.testCaseHash = testCaseHash; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public Set getPatternTemplates() { - return patternTemplates; - } - - public void setPatternTemplates(Set patternTemplates) { - this.patternTemplates = patternTemplates; - } - - @Override - public String toString() { - return "TestItemResource{" + "itemId=" + itemId - + ", uuid='" + uuid + '\'' - + ", name='" + name + '\'' - + ", codeRef='" + codeRef + '\'' - + ", description='" + description + '\'' - + ", parameters=" + parameters - + ", attributes=" + attributes - + ", type='" + type + '\'' - + ", startTime=" + startTime - + ", endTime=" + endTime - + ", status='" + status + '\'' - + ", statisticsResource=" + statisticsResource - + ", parent=" + parent - + ", pathNames=" + pathNames - + ", launchStatus='" + launchStatus + '\'' - + ", issue=" + issue - + ", hasChildren=" + hasChildren - + ", hasStats=" + hasStats - + ", launchId=" + launchId - + ", uniqueId='" + uniqueId + '\'' - + ", testCaseId='" + testCaseId + '\'' - + ", testCaseHash='" + testCaseHash + '\'' - + ", patternTemplates=" + patternTemplates - + ", retries=" + retries - + ", path='" + path + '\'' - + '}'; - } } diff --git a/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java b/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java new file mode 100644 index 0000000..9b86820 --- /dev/null +++ b/src/main/java/com/epam/ta/reportportal/ws/reporting/databind/MultiFormatDateDeserializer.java @@ -0,0 +1,74 @@ +/* + * Copyright 2024 EPAM Systems + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.epam.ta.reportportal.ws.reporting.databind; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import java.io.IOException; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; + +/** + * Deserialization class for parsing incoming dates of different formats. + * + * @author Siarhei Hrabko + */ +public class MultiFormatDateDeserializer extends JsonDeserializer { + + private static final DateTimeFormatter TIMESTAMP_FORMAT = + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("UTC")); + + private static final DateTimeFormatter LOCAL_DATE_TIME_MS_FORMAT = + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS").withZone(ZoneId.of("UTC")); + + @Override + public Instant deserialize(JsonParser parser, DeserializationContext context) throws IOException { + try { + long longDate = parser.getLongValue(); + if (parser.getText() == null) { + return Instant.ofEpochMilli(longDate); + } + // ignore + } catch (Exception e) { + // ignore + } + try { + long millis = Long.parseLong(parser.getText()); + return Instant.ofEpochMilli(millis); + } catch (Exception e) { + // ignore + } + + String strDate = parser.getText(); + DateTimeFormatter formatter = + new DateTimeFormatterBuilder().appendOptional(DateTimeFormatter.RFC_1123_DATE_TIME) + .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME) + .appendOptional(DateTimeFormatter.ISO_DATE_TIME) + .appendOptional(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + .appendOptional(TIMESTAMP_FORMAT) + .appendOptional(LOCAL_DATE_TIME_MS_FORMAT) + .toFormatter(); + + return LocalDateTime.from(formatter.parse(strDate)).toInstant(ZoneOffset.UTC); + + } +} diff --git a/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java b/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java new file mode 100644 index 0000000..81a70a7 --- /dev/null +++ b/src/test/java/com/epam/ta/reportportal/ws/reporting/deserializers/MultiFormatDateDeserializerTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2024 EPAM Systems + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.epam.ta.reportportal.ws.reporting.deserializers; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.epam.ta.reportportal.ws.reporting.databind.MultiFormatDateDeserializer; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import java.io.IOException; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + + +@ExtendWith(MockitoExtension.class) +class MultiFormatDateDeserializerTest { + + private static final Instant expectedTime = Instant.parse("2024-03-01T20:24:09.930Z"); + + @Mock + JsonParser jsonParser; + + @ParameterizedTest + @ValueSource(strings = { + "2024-03-01T20:24:09.930987Z", + "2024-03-01T20:24:09.930987654Z", + "2024-03-01T20:24:09.930Z", + "2024-03-01T20:24:09.930", + "2024-03-01T20:24:09.930+00:00", + "1709324649930" + }) + void deserializeDates(String strDate) throws IOException { + MultiFormatDateDeserializer a = new MultiFormatDateDeserializer(); + when(jsonParser.getText()).thenReturn(strDate); + Instant date = a.deserialize(jsonParser, mock(DeserializationContext.class)); + + Assertions.assertEquals(expectedTime, date.truncatedTo(ChronoUnit.MILLIS)); + } + + @ParameterizedTest + @ValueSource(longs = { + 1709324649930L, + }) + void deserializeIntegerFormat(Long longDate) throws IOException { + MultiFormatDateDeserializer a = new MultiFormatDateDeserializer(); + when(jsonParser.getLongValue()).thenReturn(longDate); + Instant date = a.deserialize(jsonParser, mock(DeserializationContext.class)); + + Assertions.assertEquals(expectedTime, date.truncatedTo(ChronoUnit.MILLIS)); + } +}