Code refactoring of hawkbit-ddi-api (#2052)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-11-16 17:56:33 +02:00
committed by GitHub
parent 9b7606f68e
commit 3411634ba3
41 changed files with 430 additions and 543 deletions

View File

@@ -24,10 +24,26 @@
<name>hawkBit :: DDI :: REST API</name> <name>hawkBit :: DDI :: REST API</name>
<dependencies> <dependencies>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-rest-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.hateoas</groupId> <groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId> <artifactId>spring-hateoas</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId> <artifactId>jackson-annotations</artifactId>
@@ -36,19 +52,6 @@
<groupId>com.fasterxml.jackson.dataformat</groupId> <groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-cbor</artifactId> <artifactId>jackson-dataformat-cbor</artifactId>
</dependency> </dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-rest-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<!-- TEST --> <!-- TEST -->
<dependency> <dependency>

View File

@@ -16,32 +16,34 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode; import lombok.Data;
import lombok.Getter;
import lombok.ToString;
/** /**
* <p> * <p>
* After the HawkBit Target has executed an action, received by a GET(URL) * After the HawkBit Target has executed an action, received by a GET(URL) request it reports the
* request it reports the completion of it to the HawkBit Server with a action * completion of it to the HawkBit Server with an action status message, i.e. with a PUT message to the
* status message, i.e. with a PUT message to the feedback channel, i.e. PUT * feedback channel, i.e. PUT URL/feedback.
* URL/feedback. This message could be used not only at the end of execution but * This message could be used not only at the end of execution but also as status updates during a longer lasting execution period.
* also as status updates during a longer lasting execution period. The format * The format of each action answer message is defined below at each action. But it is expected, that the contents of the message answers
* of each action answer message is defined below at each action. But it is * have all a similar structure:
* expected, that the contents of the message answers have all a similar * The content starts with a generic header and additional elements.
* structure: The content starts with a generic header and additional elements.
* *
* </p> * </p>
* *
* <p> * <p>
* The answer header would look like: { "time": "20140511T121314", "status": { * The answer header would look like: {
* "execution": "closed", "result": { "final": "success", "progress": {} } * "time": "20140511T121314",
* "details": [], } } * "status": {
* "execution": "closed",
* "result": {
* "final": "success",
* "progress": {}
* }
* "details": []
* }
* }
* </p> * </p>
*/ */
@Getter @Data
@EqualsAndHashCode
@ToString
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class DdiActionFeedback { public class DdiActionFeedback {

View File

@@ -13,22 +13,18 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode; import lombok.Data;
import lombok.Getter;
import lombok.ToString;
@Getter @Data
@EqualsAndHashCode
@ToString
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class DdiActivateAutoConfirmation { public class DdiActivateAutoConfirmation {
@JsonProperty(required = false) @JsonProperty
@Schema(description = "Individual value (e.g. username) stored as initiator and automatically used as confirmed" + @Schema(description = "Individual value (e.g. username) stored as initiator and automatically used as confirmed" +
" user in future actions", example = "exampleUser") " user in future actions", example = "exampleUser")
private final String initiator; private final String initiator;
@JsonProperty(required = false) @JsonProperty
@Schema(description = "Individual value to attach a remark which will be persisted when automatically " + @Schema(description = "Individual value to attach a remark which will be persisted when automatically " +
"confirming future actions", example = "exampleRemark") "confirming future actions", example = "exampleRemark")
private final String remark; private final String remark;
@@ -40,7 +36,8 @@ public class DdiActivateAutoConfirmation {
* @param remark can be null * @param remark can be null
*/ */
@JsonCreator @JsonCreator
public DdiActivateAutoConfirmation(@JsonProperty(value = "initiator") final String initiator, public DdiActivateAutoConfirmation(
@JsonProperty(value = "initiator") final String initiator,
@JsonProperty(value = "remark") final String remark) { @JsonProperty(value = "remark") final String remark) {
this.initiator = initiator; this.initiator = initiator;
this.remark = remark; this.remark = remark;

View File

@@ -13,10 +13,12 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/** /**
* Allow a target to declare running distribution set version * Allow a target to declare running distribution set version
*/ */
@Data
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class DdiAssignedVersion { public class DdiAssignedVersion {
@@ -33,20 +35,13 @@ public class DdiAssignedVersion {
* @param version Distribution set version * @param version Distribution set version
*/ */
@JsonCreator @JsonCreator
public DdiAssignedVersion(@JsonProperty(value = "name", required = true) String name, public DdiAssignedVersion(
@JsonProperty(value = "version", required = true) String version) { @JsonProperty(value = "name", required = true) final String name,
@JsonProperty(value = "version", required = true) final String version) {
this.name = name; this.name = name;
this.version = version; this.version = version;
} }
public String getName() {
return name;
}
public String getVersion() {
return version;
}
@Override @Override
public String toString() { public String toString() {
return "DdiInstalledVersion{" + "name='" + name + '\'' + ", version='" + version + '\'' + '}'; return "DdiInstalledVersion{" + "name='" + name + '\'' + ", version='" + version + '\'' + '}';

View File

@@ -33,8 +33,10 @@ public class DdiAutoConfirmationState extends RepresentationModel<DdiAutoConfirm
@NotNull @NotNull
@Schema(example = "true") @Schema(example = "true")
private boolean active; private boolean active;
@Schema(example = "exampleUserId") @Schema(example = "exampleUserId")
private String initiator; private String initiator;
@Schema(example = "exampleRemark") @Schema(example = "exampleRemark")
private String remark; private String remark;

View File

@@ -15,16 +15,12 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode; import lombok.Data;
import lombok.Getter;
import lombok.ToString;
/** /**
* Cancel action to be provided to the target. * Cancel action to be provided to the target.
*/ */
@Getter @Data
@EqualsAndHashCode
@ToString
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class DdiCancel { public class DdiCancel {
@@ -42,7 +38,8 @@ public class DdiCancel {
* @param cancelAction the action * @param cancelAction the action
*/ */
@JsonCreator @JsonCreator
public DdiCancel(@JsonProperty("id") final String id, public DdiCancel(
@JsonProperty("id") final String id,
@JsonProperty("cancelAction") final DdiCancelActionToStop cancelAction) { @JsonProperty("cancelAction") final DdiCancelActionToStop cancelAction) {
this.id = id; this.id = id;
this.cancelAction = cancelAction; this.cancelAction = cancelAction;

View File

@@ -15,16 +15,12 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode; import lombok.Data;
import lombok.Getter;
import lombok.ToString;
/** /**
* The action that has to be stopped by the target. * The action that has to be stopped by the target.
*/ */
@Getter @Data
@EqualsAndHashCode
@ToString
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class DdiCancelActionToStop { public class DdiCancelActionToStop {

View File

@@ -73,7 +73,8 @@ public class DdiChunk {
* @param artifacts download information * @param artifacts download information
* @param metadata optional as additional information for the target/device * @param metadata optional as additional information for the target/device
*/ */
public DdiChunk(final String part, final String version, final String name, final Boolean encrypted, public DdiChunk(
final String part, final String version, final String name, final Boolean encrypted,
final List<DdiArtifact> artifacts, final List<DdiMetadata> metadata) { final List<DdiArtifact> artifacts, final List<DdiMetadata> metadata) {
this.part = part; this.part = part;
this.version = version; this.version = version;

View File

@@ -17,16 +17,12 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode; import lombok.Data;
import lombok.Getter;
import lombok.ToString;
/** /**
* Feedback channel for ConfigData action. * Feedback channel for ConfigData action.
*/ */
@Getter @Data
@EqualsAndHashCode
@ToString
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
@Schema(example = """ @Schema(example = """
{ {

View File

@@ -58,11 +58,6 @@ public class DdiConfirmationBase extends RepresentationModel<DdiConfirmationBase
@NotNull @NotNull
private DdiAutoConfirmationState autoConfirm; private DdiAutoConfirmationState autoConfirm;
/**
* Constructor.
*
* @param autoConfirmState
*/
public DdiConfirmationBase(final DdiAutoConfirmationState autoConfirmState) { public DdiConfirmationBase(final DdiAutoConfirmationState autoConfirmState) {
this.autoConfirm = autoConfirmState; this.autoConfirm = autoConfirmState;
} }

View File

@@ -228,11 +228,9 @@ public class DdiConfirmationBaseAction extends RepresentationModel<DdiConfirmati
* *
* @param id of the update action * @param id of the update action
* @param confirmation chunk details * @param confirmation chunk details
* @param actionHistory containing current action status and a list of feedback messages * @param actionHistory containing current action status and a list of feedback messages received earlier from the controller.
* received earlier from the controller.
*/ */
public DdiConfirmationBaseAction(final String id, final DdiDeployment confirmation, public DdiConfirmationBaseAction(final String id, final DdiDeployment confirmation, final DdiActionHistory actionHistory) {
final DdiActionHistory actionHistory) {
this.id = id; this.id = id;
this.confirmation = confirmation; this.confirmation = confirmation;
this.actionHistory = actionHistory; this.actionHistory = actionHistory;

View File

@@ -20,18 +20,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.annotation.JsonValue;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode; import lombok.Data;
import lombok.Getter;
import lombok.ToString;
/** /**
* New update actions require confirmation when confirmation flow is switched on. This is the feedback channel for * New update actions require confirmation when confirmation flow is switched on. This is the feedback channel for
* confirmation messages for DDI API. The confirmation message has a mandatory field confirmation with possible values: * confirmation messages for DDI API. The confirmation message has a mandatory field confirmation with possible values:
* "confirmed" and "denied". * "confirmed" and "denied".
*/ */
@Getter @Data
@EqualsAndHashCode
@ToString
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class DdiConfirmationFeedback { public class DdiConfirmationFeedback {
@@ -39,13 +35,15 @@ public class DdiConfirmationFeedback {
@Valid @Valid
@Schema(description = "Action confirmation state") @Schema(description = "Action confirmation state")
private final Confirmation confirmation; private final Confirmation confirmation;
@Schema(description = "(Optional) Individual status code", example = "200") @Schema(description = "(Optional) Individual status code", example = "200")
private final Integer code; private final Integer code;
@Schema(description = "List of detailed message information", example = "[ \"Feedback message\" ]") @Schema(description = "List of detailed message information", example = "[ \"Feedback message\" ]")
private final List<String> details; private final List<String> details;
/** /**
* Constructs an confirmation-feedback * Constructs a confirmation-feedback
* *
* @param confirmation confirmation value for the action. Valid values are "Confirmed" and "Denied * @param confirmation confirmation value for the action. Valid values are "Confirmed" and "Denied
* @param code code for confirmation * @param code code for confirmation

View File

@@ -39,14 +39,17 @@ public class DdiDeployment {
Handling for the download part of the provisioning process ('skip': do not download yet, 'attempt': server asks Handling for the download part of the provisioning process ('skip': do not download yet, 'attempt': server asks
to download, 'forced': server requests immediate download)""") to download, 'forced': server requests immediate download)""")
private HandlingType download; private HandlingType download;
@Schema(description = """ @Schema(description = """
Handling for the update part of the provisioning process ('skip': do not update yet, Handling for the update part of the provisioning process ('skip': do not update yet,
'attempt': server asks to update, 'forced': server requests immediate update)""") 'attempt': server asks to update, 'forced': server requests immediate update)""")
private HandlingType update; private HandlingType update;
@JsonProperty("chunks") @JsonProperty("chunks")
@NotNull @NotNull
@Schema(description = "Software chunks of an update. In server mapped by Software Module") @Schema(description = "Software chunks of an update. In server mapped by Software Module")
private List<DdiChunk> chunks; private List<DdiChunk> chunks;
@Schema(description = """ @Schema(description = """
Separation of download and installation by defining a maintenance window for the installation. Status shows if Separation of download and installation by defining a maintenance window for the installation. Status shows if
currently in a window""") currently in a window""")
@@ -59,14 +62,12 @@ public class DdiDeployment {
* @param update handling type * @param update handling type
* @param chunks to handle. * @param chunks to handle.
* @param maintenanceWindow specifying whether there is a maintenance schedule associated. * @param maintenanceWindow specifying whether there is a maintenance schedule associated.
* If it is, the value is either 'available' (i.e. the * If it is, the value is either 'available' (i.e. the maintenance window is now available as per defined schedule
* maintenance window is now available as per defined schedule * and the update can progress) or 'unavailable' (implying that maintenance window is not available now and update should not
* and the update can progress) or 'unavailable' (implying that * be attempted). If there is no maintenance schedule defined, the parameter is null.
* maintenance window is not available now and update should not
* be attempted). If there is no maintenance schedule defined,
* the parameter is null.
*/ */
public DdiDeployment(final HandlingType download, final HandlingType update, final List<DdiChunk> chunks, public DdiDeployment(
final HandlingType download, final HandlingType update, final List<DdiChunk> chunks,
final DdiMaintenanceWindowStatus maintenanceWindow) { final DdiMaintenanceWindowStatus maintenanceWindow) {
this.download = download; this.download = download;
this.update = update; this.update = update;

View File

@@ -222,8 +222,7 @@ public class DdiDeploymentBase extends RepresentationModel<DdiDeploymentBase> {
* *
* @param id of the update action * @param id of the update action
* @param deployment details * @param deployment details
* @param actionHistory containing current action status and a list of feedback * @param actionHistory containing current action status and a list of feedback messages received earlier from the controller.
* messages received earlier from the controller.
*/ */
public DdiDeploymentBase(final String id, final DdiDeployment deployment, final DdiActionHistory actionHistory) { public DdiDeploymentBase(final String id, final DdiDeployment deployment, final DdiActionHistory actionHistory) {
this.id = id; this.id = id;

View File

@@ -15,16 +15,12 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode; import lombok.Data;
import lombok.Getter;
import lombok.ToString;
/** /**
* Additional metadata to be provided for the target/device. * Additional metadata to be provided for the target/device.
*/ */
@Getter @Data
@EqualsAndHashCode
@ToString
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class DdiMetadata { public class DdiMetadata {

View File

@@ -14,10 +14,19 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
/** /**
* Polling interval for the SP target. * Polling interval for the SP target.
*/ */
@NoArgsConstructor(access = AccessLevel.PUBLIC)// needed for json create
@Getter
@EqualsAndHashCode
@ToString
@JsonInclude(Include.NON_NULL) @JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "Suggested sleep time between polls") @Schema(description = "Suggested sleep time between polls")
@@ -35,15 +44,4 @@ public class DdiPolling {
public DdiPolling(final String sleep) { public DdiPolling(final String sleep) {
this.sleep = sleep; this.sleep = sleep;
} }
/**
* Constructor.
*/
public DdiPolling() {
// needed for json create
}
public String getSleep() {
return sleep;
}
} }

View File

@@ -15,17 +15,12 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode; import lombok.Data;
import lombok.Getter;
import lombok.ToString;
/** /**
* Action fulfillment progress by means of gives the achieved amount of maximal * Action fulfillment progress by means of gives the achieved amount of maximal of possible levels.
* of possible levels.
*/ */
@Getter @Data
@EqualsAndHashCode
@ToString
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class DdiProgress { public class DdiProgress {

View File

@@ -17,17 +17,12 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.annotation.JsonValue;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode; import lombok.Data;
import lombok.Getter;
import lombok.ToString;
/** /**
* Result information of the action progress which can by an intermediate or * Result information of the action progress which can by an intermediate or final update.
* final update.
*/ */
@Getter @Data
@EqualsAndHashCode
@ToString
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class DdiResult { public class DdiResult {
@@ -35,6 +30,7 @@ public class DdiResult {
@Valid @Valid
@Schema(description = "Result of the action execution") @Schema(description = "Result of the action execution")
private final FinalResult finished; private final FinalResult finished;
@Schema(description = "Progress assumption of the device (currently not supported)") @Schema(description = "Progress assumption of the device (currently not supported)")
private final DdiProgress progress; private final DdiProgress progress;
@@ -45,7 +41,8 @@ public class DdiResult {
* @param progress if not yet finished * @param progress if not yet finished
*/ */
@JsonCreator @JsonCreator
public DdiResult(@JsonProperty("finished") final FinalResult finished, public DdiResult(
@JsonProperty("finished") final FinalResult finished,
@JsonProperty("progress") final DdiProgress progress) { @JsonProperty("progress") final DdiProgress progress) {
this.finished = finished; this.finished = finished;
this.progress = progress; this.progress = progress;

View File

@@ -20,16 +20,12 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.annotation.JsonValue;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode; import lombok.Data;
import lombok.Getter;
import lombok.ToString;
/** /**
* Details status information concerning the action processing. * Details status information concerning the action processing.
*/ */
@Getter @Data
@EqualsAndHashCode
@ToString
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "Target action status") @Schema(description = "Target action status")
public class DdiStatus { public class DdiStatus {
@@ -38,12 +34,15 @@ public class DdiStatus {
@Valid @Valid
@Schema(description = "Status of the action execution") @Schema(description = "Status of the action execution")
private final ExecutionStatus execution; private final ExecutionStatus execution;
@NotNull @NotNull
@Valid @Valid
@Schema(description = "Result of the action execution") @Schema(description = "Result of the action execution")
private final DdiResult result; private final DdiResult result;
@Schema(description = "(Optional) Individual status code", example = "200") @Schema(description = "(Optional) Individual status code", example = "200")
private final Integer code; private final Integer code;
@Schema(description = "List of details message information", example = "[ \"Some feedback\" ]") @Schema(description = "List of details message information", example = "[ \"Some feedback\" ]")
private final List<String> details; private final List<String> details;
@@ -56,8 +55,10 @@ public class DdiStatus {
* @param details as optional addition * @param details as optional addition
*/ */
@JsonCreator @JsonCreator
public DdiStatus(@JsonProperty("execution") final ExecutionStatus execution, public DdiStatus(
@JsonProperty("result") final DdiResult result, @JsonProperty("code") final Integer code, @JsonProperty("execution") final ExecutionStatus execution,
@JsonProperty("result") final DdiResult result,
@JsonProperty("code") final Integer code,
@JsonProperty("details") final List<String> details) { @JsonProperty("details") final List<String> details) {
this.execution = execution; this.execution = execution;
this.result = result; this.result = result;
@@ -74,8 +75,7 @@ public class DdiStatus {
} }
/** /**
* The element status contains information about the execution of the * The element status contains information about the execution of the operation.
* operation.
*/ */
public enum ExecutionStatus { public enum ExecutionStatus {
/** /**
@@ -118,7 +118,7 @@ public class DdiStatus {
*/ */
DOWNLOAD("download"); DOWNLOAD("download");
private String name; private final String name;
ExecutionStatus(final String name) { ExecutionStatus(final String name) {
this.name = name; this.name = name;

View File

@@ -35,7 +35,7 @@ public enum DdiUpdateMode {
*/ */
REMOVE("remove"); REMOVE("remove");
private String name; private final String name;
DdiUpdateMode(final String name) { DdiUpdateMode(final String name) {
this.name = name; this.name = name;

View File

@@ -9,9 +9,13 @@
*/ */
package org.eclipse.hawkbit.ddi.rest.api; package org.eclipse.hawkbit.ddi.rest.api;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
/** /**
* Constants for the direct device integration rest resources. * Constants for the direct device integration rest resources.
*/ */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class DdiRestConstants { public final class DdiRestConstants {
/** /**
@@ -77,8 +81,4 @@ public final class DdiRestConstants {
* can reuse - even the Jackson data converter simply hardcodes this. * can reuse - even the Jackson data converter simply hardcodes this.
*/ */
public static final String MEDIA_TYPE_CBOR = "application/cbor"; public static final String MEDIA_TYPE_CBOR = "application/cbor";
private DdiRestConstants() {
// constant class, private constructor.
}
} }

View File

@@ -81,10 +81,10 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts",
+ "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts", produces = { MediaTypes.HAL_JSON_VALUE, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity<List<DdiArtifact>> getSoftwareModulesArtifacts(
ResponseEntity<List<DdiArtifact>> getSoftwareModulesArtifacts(@PathVariable("tenant") final String tenant, @PathVariable("tenant") final String tenant,
@PathVariable("controllerId") final String controllerId, @PathVariable("controllerId") final String controllerId,
@PathVariable("softwareModuleId") final Long softwareModuleId); @PathVariable("softwareModuleId") final Long softwareModuleId);
@@ -120,9 +120,10 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}", produces = { @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}",
MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
ResponseEntity<DdiControllerBase> getControllerBase(@PathVariable("tenant") final String tenant, ResponseEntity<DdiControllerBase> getControllerBase(
@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") final String controllerId); @PathVariable("controllerId") final String controllerId);
/** /**
@@ -134,8 +135,7 @@ public interface DdiRootControllerRestApi {
* @param softwareModuleId of the parent software module * @param softwareModuleId of the parent software module
* @param fileName of the related local artifact * @param fileName of the related local artifact
* @return response of the servlet which in case of success is status code * @return response of the servlet which in case of success is status code
* {@link HttpStatus#OK} or in case of partial download * {@link HttpStatus#OK} or in case of partial download {@link HttpStatus#PARTIAL_CONTENT}.
* {@link HttpStatus#PARTIAL_CONTENT}.
*/ */
@Operation(summary = "Artifact download", description = "Handles GET DdiArtifact download request. This could be " + @Operation(summary = "Artifact download", description = "Handles GET DdiArtifact download request. This could be " +
"full or partial (as specified by RFC7233 (Range Requests)) download request.") "full or partial (as specified by RFC7233 (Range Requests)) download request.")
@@ -172,8 +172,7 @@ public interface DdiRootControllerRestApi {
* @param controllerId of the target * @param controllerId of the target
* @param softwareModuleId of the parent software module * @param softwareModuleId of the parent software module
* @param fileName of the related local artifact * @param fileName of the related local artifact
* @return {@link ResponseEntity} with status {@link HttpStatus#OK} if * @return {@link ResponseEntity} with status {@link HttpStatus#OK} if successful
* successful
*/ */
@Operation(summary = "MD5 checksum download", @Operation(summary = "MD5 checksum download",
description = "Handles GET {@link DdiArtifact} MD5 checksum file download request.") description = "Handles GET {@link DdiArtifact} MD5 checksum file download request.")
@@ -196,10 +195,10 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{fileName}" +
+ "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{fileName}" DdiRestConstants.ARTIFACT_MD5_DWNL_SUFFIX, produces = MediaType.TEXT_PLAIN_VALUE)
+ DdiRestConstants.ARTIFACT_MD5_DWNL_SUFFIX, produces = MediaType.TEXT_PLAIN_VALUE) ResponseEntity<Void> downloadArtifactMd5(
ResponseEntity<Void> downloadArtifactMd5(@PathVariable("tenant") final String tenant, @PathVariable("tenant") final String tenant,
@PathVariable("controllerId") final String controllerId, @PathVariable("controllerId") final String controllerId,
@PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("fileName") final String fileName); @PathVariable("fileName") final String fileName);
@@ -209,26 +208,15 @@ public interface DdiRootControllerRestApi {
* *
* @param tenant of the request * @param tenant of the request
* @param controllerId of the target * @param controllerId of the target
* @param actionId of the {@link DdiDeploymentBase} that matches to active * @param actionId of the {@link DdiDeploymentBase} that matches to active actions.
* actions. * @param resource a hashcode of the resource which indicates if the action has been changed, e.g. from 'soft' to 'force' and
* @param resource an hashcode of the resource which indicates if the action has * the eTag needs to be re-generated
* been changed, e.g. from 'soft' to 'force' and the eTag needs * @param actionHistoryMessageCount specifies the number of messages to be returned from action history. Regardless of the passed value,
* to be re-generated * in order to restrict resource utilization by controllers, maximum number of
* @param actionHistoryMessageCount specifies the number of messages to be returned from action * messages that are retrieved from database is limited by {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}.
* history. Regardless of the passed value, in order to restrict * actionHistoryMessageCount less than zero: retrieves the maximum allowed number of action status messages from history;
* resource utilization by controllers, maximum number of * actionHistoryMessageCount equal to zero: does not retrieve any message;
* messages that are retrieved from database is limited by * actionHistoryMessageCount greater than zero: retrieves the specified number of messages, limited by maximum allowed number.
* {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}.
*
* actionHistoryMessageCount less than zero: retrieves the
* maximum allowed number of action status messages from history;
*
* actionHistoryMessageCount equal to zero: does not retrieve any
* message;
*
* actionHistoryMessageCount greater than zero: retrieves the
* specified number of messages, limited by maximum allowed
* number.
* @return the response * @return the response
*/ */
@Operation(summary = "Resource for software module (Deployment Base)", description = """ @Operation(summary = "Resource for software module (Deployment Base)", description = """
@@ -270,9 +258,8 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.DEPLOYMENT_BASE_ACTION + "/{actionId}",
+ DdiRestConstants.DEPLOYMENT_BASE_ACTION + "/{actionId}", produces = { MediaTypes.HAL_JSON_VALUE, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
ResponseEntity<DdiDeploymentBase> getControllerDeploymentBaseAction(@PathVariable("tenant") final String tenant, ResponseEntity<DdiDeploymentBase> getControllerDeploymentBaseAction(@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId, @PathVariable("controllerId") @NotEmpty final String controllerId,
@PathVariable("actionId") @NotNull final Long actionId, @PathVariable("actionId") @NotNull final Long actionId,
@@ -321,16 +308,13 @@ public interface DdiRootControllerRestApi {
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " + @ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " +
"supported by the server for this resource.", "supported by the server for this resource.",
content = @Content(mediaType = "application/json", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts " + @ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts " +
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
schema = @Schema(hidden = true)))
}) })
@PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" @PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.DEPLOYMENT_BASE_ACTION +
+ DdiRestConstants.DEPLOYMENT_BASE_ACTION + "/{actionId}/" + DdiRestConstants.FEEDBACK, consumes = { "/{actionId}/" + DdiRestConstants.FEEDBACK, consumes = { MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
ResponseEntity<Void> postDeploymentBaseActionFeedback(@Valid final DdiActionFeedback feedback, ResponseEntity<Void> postDeploymentBaseActionFeedback(@Valid final DdiActionFeedback feedback,
@PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId, @PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId,
@PathVariable("actionId") @NotNull final Long actionId); @PathVariable("actionId") @NotNull final Long actionId);
@@ -370,11 +354,12 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@PutMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" @PutMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CONFIG_DATA_ACTION,
+ DdiRestConstants.CONFIG_DATA_ACTION, consumes = { MediaType.APPLICATION_JSON_VALUE, consumes = { MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity<Void> putConfigData(
ResponseEntity<Void> putConfigData(@Valid final DdiConfigData configData, @Valid final DdiConfigData configData,
@PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId); @PathVariable("tenant") final String tenant,
@PathVariable("controllerId") final String controllerId);
/** /**
* RequestMethod.GET method for the {@link DdiCancel} action. * RequestMethod.GET method for the {@link DdiCancel} action.
@@ -404,16 +389,15 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CANCEL_ACTION @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CANCEL_ACTION + "/{actionId}",
+ "/{actionId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity<DdiCancel> getControllerCancelAction(
ResponseEntity<DdiCancel> getControllerCancelAction(@PathVariable("tenant") final String tenant, @PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId, @PathVariable("controllerId") @NotEmpty final String controllerId,
@PathVariable("actionId") @NotNull final Long actionId); @PathVariable("actionId") @NotNull final Long actionId);
/** /**
* RequestMethod.POST method receiving the {@link DdiActionFeedback} from * RequestMethod.POST method receiving the {@link DdiActionFeedback} from the target.
* the target.
* *
* @param feedback the {@link DdiActionFeedback} from the target. * @param feedback the {@link DdiActionFeedback} from the target.
* @param tenant of the client * @param tenant of the client
@@ -448,39 +432,27 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CANCEL_ACTION @PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CANCEL_ACTION + "/{actionId}/" +
+ "/{actionId}/" + DdiRestConstants.FEEDBACK, consumes = { MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.FEEDBACK, consumes = { MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity<Void> postCancelActionFeedback(
ResponseEntity<Void> postCancelActionFeedback(@Valid final DdiActionFeedback feedback, @Valid final DdiActionFeedback feedback,
@PathVariable("tenant") final String tenant, @PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId, @PathVariable("controllerId") @NotEmpty final String controllerId,
@PathVariable("actionId") @NotNull final Long actionId); @PathVariable("actionId") @NotNull final Long actionId);
/** /**
* Resource for installed distribution set to retrieve the last successfully * Resource for installed distribution set to retrieve the last successfully finished action.
* finished action.
* *
* @param tenant of the request * @param tenant of the request
* @param controllerId of the target * @param controllerId of the target
* @param actionId of the {@link DdiDeploymentBase} that matches to installed * @param actionId of the {@link DdiDeploymentBase} that matches to installed action.
* action.
* @param actionHistoryMessageCount specifies the number of messages to be returned from action * @param actionHistoryMessageCount specifies the number of messages to be returned from action
* history. Regardless of the passed value, in order to restrict * history. Regardless of the passed value, in order to restrict resource utilization by controllers, maximum number of
* resource utilization by controllers, maximum number of * messages that are retrieved from database is limited by {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}.
* messages that are retrieved from database is limited by * actionHistoryMessageCount less than zero: retrieves the maximum allowed number of action status messages from history;
* {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}. * actionHistoryMessageCount equal to zero: does not retrieve any message;
* * actionHistoryMessageCount greater than zero: retrieves the specified number of messages, limited by maximum allowed number.
* actionHistoryMessageCount less than zero: retrieves the * @return the {@link DdiDeploymentBase}. The response is of same format as for the /deploymentBase resource.
* maximum allowed number of action status messages from history;
*
* actionHistoryMessageCount equal to zero: does not retrieve any
* message;
*
* actionHistoryMessageCount greater than zero: retrieves the
* specified number of messages, limited by maximum allowed
* number.
* @return the {@link DdiDeploymentBase}. The response is of same format as
* for the /deploymentBase resource.
*/ */
@Operation(summary = "Previously installed action", description = """ @Operation(summary = "Previously installed action", description = """
Resource to receive information of the previous installation. Can be used to re-retrieve artifacts of Resource to receive information of the previous installation. Can be used to re-retrieve artifacts of
@@ -514,14 +486,14 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.INSTALLED_BASE_ACTION + "/{actionId}",
+ DdiRestConstants.INSTALLED_BASE_ACTION + "/{actionId}", produces = { MediaTypes.HAL_JSON_VALUE, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
ResponseEntity<DdiDeploymentBase> getControllerInstalledAction(@PathVariable("tenant") final String tenant, ResponseEntity<DdiDeploymentBase> getControllerInstalledAction(@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId, @PathVariable("controllerId") @NotEmpty final String controllerId,
@PathVariable("actionId") @NotNull final Long actionId, @PathVariable("actionId") @NotNull final Long actionId,
@RequestParam(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING @RequestParam(
+ "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount); value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "actionHistory",
defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount);
/** /**
* Returns the confirmation base with the current auto-confirmation state * Returns the confirmation base with the current auto-confirmation state
@@ -559,10 +531,10 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CONFIRMATION_BASE,
+ DdiRestConstants.CONFIRMATION_BASE, produces = { MediaTypes.HAL_JSON_VALUE, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity<DdiConfirmationBase> getConfirmationBase(
ResponseEntity<DdiConfirmationBase> getConfirmationBase(@PathVariable("tenant") final String tenant, @PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId); @PathVariable("controllerId") @NotEmpty final String controllerId);
/** /**
@@ -570,26 +542,15 @@ public interface DdiRootControllerRestApi {
* *
* @param tenant of the request * @param tenant of the request
* @param controllerId of the target * @param controllerId of the target
* @param actionId of the {@link DdiConfirmationBaseAction} that matches to * @param actionId of the {@link DdiConfirmationBaseAction} that matches to active actions in WAITING_FOR_CONFIRMATION status.
* active actions in WAITING_FOR_CONFIRMATION status. * @param resource a hashcode of the resource which indicates if the action has been changed, e.g. from 'soft' to 'force' and the eTag
* @param resource an hashcode of the resource which indicates if the action has * needs to be re-generated
* been changed, e.g. from 'soft' to 'force' and the eTag needs * @param actionHistoryMessageCount specifies the number of messages to be returned from action history. Regardless of the passed value,
* to be re-generated * in order to restrict resource utilization by controllers, maximum number of messages that are retrieved from database is limited
* @param actionHistoryMessageCount specifies the number of messages to be returned from action * by {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}.
* history. Regardless of the passed value, in order to restrict * actionHistoryMessageCount less than zero: retrieves the maximum allowed number of action status messages from history;
* resource utilization by controllers, maximum number of * actionHistoryMessageCount equal to zero: does not retrieve any message;
* messages that are retrieved from database is limited by * actionHistoryMessageCount greater than zero: retrieves the specified number of messages, limited by maximum allowed number.
* {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}.
*
* actionHistoryMessageCount less than zero: retrieves the
* maximum allowed number of action status messages from history;
*
* actionHistoryMessageCount equal to zero: does not retrieve any
* message;
*
* actionHistoryMessageCount greater than zero: retrieves the
* specified number of messages, limited by maximum allowed
* number.
* @return the response * @return the response
*/ */
@Operation(summary = "Confirmation status of an action", description = """ @Operation(summary = "Confirmation status of an action", description = """
@@ -627,14 +588,13 @@ public interface DdiRootControllerRestApi {
ResponseEntity<DdiConfirmationBaseAction> getConfirmationBaseAction(@PathVariable("tenant") final String tenant, ResponseEntity<DdiConfirmationBaseAction> getConfirmationBaseAction(@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId, @PathVariable("controllerId") @NotEmpty final String controllerId,
@PathVariable("actionId") @NotNull final Long actionId, @PathVariable("actionId") @NotNull final Long actionId,
@RequestParam(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING @RequestParam(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "c", required = false, defaultValue = "-1") final int resource,
+ "c", required = false, defaultValue = "-1") final int resource, @RequestParam(
@RequestParam(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "actionHistory",
+ "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount); defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount);
/** /**
* This is the feedback channel for the {@link DdiConfirmationBaseAction} * This is the feedback channel for the {@link DdiConfirmationBaseAction} action.
* action.
* *
* @param tenant of the client * @param tenant of the client
* @param feedback to provide * @param feedback to provide
@@ -674,24 +634,22 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" @PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CONFIRMATION_BASE + "/{actionId}/" +
+ DdiRestConstants.CONFIRMATION_BASE + "/{actionId}/" + DdiRestConstants.FEEDBACK, consumes = { DdiRestConstants.FEEDBACK, consumes = { MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity<Void> postConfirmationActionFeedback(
ResponseEntity<Void> postConfirmationActionFeedback(@Valid final DdiConfirmationFeedback feedback, @Valid final DdiConfirmationFeedback feedback,
@PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId, @PathVariable("tenant") final String tenant,
@PathVariable("controllerId") final String controllerId,
@PathVariable("actionId") @NotNull final Long actionId); @PathVariable("actionId") @NotNull final Long actionId);
/** /**
* Activate auto confirmation for a given controllerId. Will use the * Activate auto confirmation for a given controllerId. Will use the provided initiator and remark field from the provided
* provided initiator and remark field from the provided * {@link DdiActivateAutoConfirmation}. If not present, the values will be prefilled with a default remark and the CONTROLLER as initiator.
* {@link DdiActivateAutoConfirmation}. If not present, the values will be
* prefilled with a default remark and the CONTROLLER as initiator.
* *
* @param tenant the controllerId is corresponding too * @param tenant the controllerId is corresponding too
* @param controllerId to activate auto-confirmation for * @param controllerId to activate auto-confirmation for
* @param body as {@link DdiActivateAutoConfirmation} * @param body as {@link DdiActivateAutoConfirmation}
* @return {@link org.springframework.http.HttpStatus#OK} if successful or * @return {@link org.springframework.http.HttpStatus#OK} if successful or {@link org.springframework.http.HttpStatus#CONFLICT} in case
* {@link org.springframework.http.HttpStatus#CONFLICT} in case
* auto-confirmation was active already. * auto-confirmation was active already.
*/ */
@Operation(summary = "Interface to activate auto-confirmation for a specific device", description = """ @Operation(summary = "Interface to activate auto-confirmation for a specific device", description = """
@@ -724,10 +682,10 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" @PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CONFIRMATION_BASE + "/" +
+ DdiRestConstants.CONFIRMATION_BASE + "/" + DdiRestConstants.AUTO_CONFIRM_ACTIVATE, consumes = { DdiRestConstants.AUTO_CONFIRM_ACTIVATE, consumes = { MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity<Void> activateAutoConfirmation(
ResponseEntity<Void> activateAutoConfirmation(@PathVariable("tenant") final String tenant, @PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId, @PathVariable("controllerId") @NotEmpty final String controllerId,
@Valid @RequestBody(required = false) final DdiActivateAutoConfirmation body); @Valid @RequestBody(required = false) final DdiActivateAutoConfirmation body);
@@ -767,16 +725,16 @@ public interface DdiRootControllerRestApi {
"and the client has to wait another second.", "and the client has to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" @PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CONFIRMATION_BASE + "/" +
+ DdiRestConstants.CONFIRMATION_BASE + "/" + DdiRestConstants.AUTO_CONFIRM_DEACTIVATE) DdiRestConstants.AUTO_CONFIRM_DEACTIVATE)
ResponseEntity<Void> deactivateAutoConfirmation(@PathVariable("tenant") final String tenant, ResponseEntity<Void> deactivateAutoConfirmation(
@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId); @PathVariable("controllerId") @NotEmpty final String controllerId);
/** /**
* Assign an already installed distribution for a target * Assign an already installed distribution for a target
* *
* @param tenant of the client * @param tenant of the client to provide
* to provide
* @param controllerId of the target that matches to controller id * @param controllerId of the target that matches to controller id
* @param ddiAssignedVersion as {@link DdiAssignedVersion} * @param ddiAssignedVersion as {@link DdiAssignedVersion}
* @return the response * @return the response
@@ -787,20 +745,35 @@ public interface DdiRootControllerRestApi {
""") """)
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved"), @ApiResponse(responseCode = "200", description = "Successfully retrieved"),
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))), @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
@ApiResponse(responseCode = "401", description = "The request requires user authentication.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or data volume restriction applies.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), @ApiResponse(responseCode = "401", description = "The request requires user authentication.",
@ApiResponse(responseCode = "404", description = "Target or Distribution not found", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), @ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) " +
@ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), "or data volume restriction applies.",
@ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another user in another request at the same time. You may retry your modification request.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "410", description = "Action is not active anymore.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), @ApiResponse(responseCode = "404", description = "Target or Distribution not found",
@ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not supported by the server for this resource.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts and the client has to wait another second.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another user in another " +
"request at the same time. You may retry your modification request.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "410", description = "Action is not active anymore.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not supported by the server " +
"for this resource.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts and the client has " +
"to wait another second.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
}) })
@PutMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" @PutMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.INSTALLED_BASE_ACTION,
+ DdiRestConstants.INSTALLED_BASE_ACTION, consumes = { consumes = { MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR })
MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity<Void> setAsssignedOfflineVersion(
ResponseEntity<Void> setAsssignedOfflineVersion(@Valid DdiAssignedVersion ddiAssignedVersion, @Valid DdiAssignedVersion ddiAssignedVersion,
@PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId); @PathVariable("tenant") final String tenant,
@PathVariable("controllerId") final String controllerId);
} }

View File

@@ -23,7 +23,6 @@ import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import io.qameta.allure.Description; import io.qameta.allure.Description;
import io.qameta.allure.Feature; import io.qameta.allure.Feature;
import io.qameta.allure.Story; import io.qameta.allure.Story;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
@@ -39,7 +38,7 @@ class DdiActionFeedbackTest {
@Description("Verify the correct serialization and deserialization of the model with minimal payload") @Description("Verify the correct serialization and deserialization of the model with minimal payload")
void shouldSerializeAndDeserializeObjectWithoutOptionalValues() throws IOException { void shouldSerializeAndDeserializeObjectWithoutOptionalValues() throws IOException {
// Setup // Setup
final DdiStatus ddiStatus = new DdiStatus(DdiStatus.ExecutionStatus.CLOSED, null, null, Lists.emptyList()); final DdiStatus ddiStatus = new DdiStatus(DdiStatus.ExecutionStatus.CLOSED, null, null, Collections.emptyList());
final DdiActionFeedback ddiActionFeedback = new DdiActionFeedback(null, ddiStatus); final DdiActionFeedback ddiActionFeedback = new DdiActionFeedback(null, ddiStatus);
// Test // Test
@@ -61,8 +60,7 @@ class DdiActionFeedbackTest {
// Test // Test
final String serializedDdiActionFeedback = mapper.writeValueAsString(ddiActionFeedback); final String serializedDdiActionFeedback = mapper.writeValueAsString(ddiActionFeedback);
final DdiActionFeedback deserializedDdiActionFeedback = mapper.readValue(serializedDdiActionFeedback, final DdiActionFeedback deserializedDdiActionFeedback = mapper.readValue(serializedDdiActionFeedback, DdiActionFeedback.class);
DdiActionFeedback.class);
assertThat(serializedDdiActionFeedback).contains(time); assertThat(serializedDdiActionFeedback).contains(time);
assertThat(deserializedDdiActionFeedback.getTime()).isEqualTo(time); assertThat(deserializedDdiActionFeedback.getTime()).isEqualTo(time);
@@ -104,5 +102,4 @@ class DdiActionFeedbackTest {
assertThat(deserializedDdiActionFeedback.getStatus().getDetails()).hasSize(1); assertThat(deserializedDdiActionFeedback.getStatus().getDetails()).hasSize(1);
}); });
} }
} }

View File

@@ -43,9 +43,7 @@ public class DdiActionHistoryTest {
// Test // Test
final String serializedDdiActionHistory = OBJECT_MAPPER.writeValueAsString(ddiActionHistory); final String serializedDdiActionHistory = OBJECT_MAPPER.writeValueAsString(ddiActionHistory);
final DdiActionHistory deserializedDdiActionHistory = OBJECT_MAPPER.readValue(serializedDdiActionHistory, final DdiActionHistory deserializedDdiActionHistory = OBJECT_MAPPER.readValue(serializedDdiActionHistory, DdiActionHistory.class);
DdiActionHistory.class);
assertThat(serializedDdiActionHistory).contains(actionStatus, messages.get(0), messages.get(1)); assertThat(serializedDdiActionHistory).contains(actionStatus, messages.get(0), messages.get(1));
assertThat(deserializedDdiActionHistory.toString()).contains(actionStatus, messages.get(0), messages.get(1)); assertThat(deserializedDdiActionHistory.toString()).contains(actionStatus, messages.get(0), messages.get(1));
} }
@@ -63,7 +61,6 @@ public class DdiActionHistoryTest {
// Test // Test
final DdiActionHistory ddiActionHistory = OBJECT_MAPPER.readValue(serializedDdiActionHistory, DdiActionHistory.class); final DdiActionHistory ddiActionHistory = OBJECT_MAPPER.readValue(serializedDdiActionHistory, DdiActionHistory.class);
assertThat(ddiActionHistory.toString()).contains("SomeAction", "Some message"); assertThat(ddiActionHistory.toString()).contains("SomeAction", "Some message");
} }

View File

@@ -29,22 +29,20 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiArtifactHashTest { public class DdiArtifactHashTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
String sha1Hash = "11111"; final String sha1Hash = "11111";
String md5Hash = "22222"; final String md5Hash = "22222";
String sha256Hash = "33333"; final String sha256Hash = "33333";
DdiArtifactHash DdiArtifact = new DdiArtifactHash(sha1Hash, md5Hash, sha256Hash); final DdiArtifactHash DdiArtifact = new DdiArtifactHash(sha1Hash, md5Hash, sha256Hash);
// Test // Test
String serializedDdiArtifact = mapper.writeValueAsString(DdiArtifact); final String serializedDdiArtifact = OBJECT_MAPPER.writeValueAsString(DdiArtifact);
DdiArtifactHash deserializedDdiArtifact = mapper.readValue(serializedDdiArtifact, final DdiArtifactHash deserializedDdiArtifact = OBJECT_MAPPER.readValue(serializedDdiArtifact, DdiArtifactHash.class);
DdiArtifactHash.class);
assertThat(serializedDdiArtifact).contains(sha1Hash, md5Hash, sha256Hash); assertThat(serializedDdiArtifact).contains(sha1Hash, md5Hash, sha256Hash);
assertThat(deserializedDdiArtifact.getSha1()).isEqualTo(sha1Hash); assertThat(deserializedDdiArtifact.getSha1()).isEqualTo(sha1Hash);
assertThat(deserializedDdiArtifact.getMd5()).isEqualTo(md5Hash); assertThat(deserializedDdiArtifact.getMd5()).isEqualTo(md5Hash);
@@ -55,11 +53,10 @@ public class DdiArtifactHashTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiArtifact = "{\"sha1\": \"123\", \"md5\": \"456\", \"sha256\": \"789\", \"unknownProperty\": \"test\"}"; final String serializedDdiArtifact = "{\"sha1\": \"123\", \"md5\": \"456\", \"sha256\": \"789\", \"unknownProperty\": \"test\"}";
// Test // Test
DdiArtifactHash ddiArtifact = mapper.readValue(serializedDdiArtifact, DdiArtifactHash.class); final DdiArtifactHash ddiArtifact = OBJECT_MAPPER.readValue(serializedDdiArtifact, DdiArtifactHash.class);
assertThat(ddiArtifact.getSha1()).isEqualTo("123"); assertThat(ddiArtifact.getSha1()).isEqualTo("123");
assertThat(ddiArtifact.getMd5()).isEqualTo("456"); assertThat(ddiArtifact.getMd5()).isEqualTo("456");
assertThat(ddiArtifact.getSha256()).isEqualTo("789"); assertThat(ddiArtifact.getSha256()).isEqualTo("789");
@@ -69,11 +66,10 @@ public class DdiArtifactHashTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiArtifact = "{\"sha1\": [123], \"md5\": 456, \"sha256\": \"789\""; final String serializedDdiArtifact = "{\"sha1\": [123], \"md5\": 456, \"sha256\": \"789\"";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiArtifact, DdiArtifactHash.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiArtifact, DdiArtifactHash.class));
} }
} }

View File

@@ -29,25 +29,24 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiArtifactTest { public class DdiArtifactTest {
private ObjectMapper mapper = new ObjectMapper(); private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
String filename = "testfile.txt"; final String filename = "testfile.txt";
DdiArtifactHash hashes = new DdiArtifactHash("123", "456", "789"); final DdiArtifactHash hashes = new DdiArtifactHash("123", "456", "789");
Long size = 12345L; final Long size = 12345L;
DdiArtifact ddiArtifact = new DdiArtifact(); final DdiArtifact ddiArtifact = new DdiArtifact();
ddiArtifact.setFilename(filename); ddiArtifact.setFilename(filename);
ddiArtifact.setHashes(hashes); ddiArtifact.setHashes(hashes);
ddiArtifact.setSize(size); ddiArtifact.setSize(size);
// Test // Test
String serializedDdiArtifact = mapper.writeValueAsString(ddiArtifact); final String serializedDdiArtifact = OBJECT_MAPPER.writeValueAsString(ddiArtifact);
DdiArtifact deserializedDdiArtifact = mapper.readValue(serializedDdiArtifact, DdiArtifact.class); final DdiArtifact deserializedDdiArtifact = OBJECT_MAPPER.readValue(serializedDdiArtifact, DdiArtifact.class);
assertThat(serializedDdiArtifact).contains(filename, "12345"); assertThat(serializedDdiArtifact).contains(filename, "12345");
assertThat(deserializedDdiArtifact.getFilename()).isEqualTo(filename); assertThat(deserializedDdiArtifact.getFilename()).isEqualTo(filename);
assertThat(deserializedDdiArtifact.getSize()).isEqualTo(size); assertThat(deserializedDdiArtifact.getSize()).isEqualTo(size);
@@ -60,11 +59,10 @@ public class DdiArtifactTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiArtifact = "{\"filename\":\"test.file\",\"hashes\":{\"sha1\":\"123\",\"md5\":\"456\",\"sha256\":\"789\"},\"size\":111,\"links\":[],\"unknownProperty\": \"test\"}"; final String serializedDdiArtifact = "{\"filename\":\"test.file\",\"hashes\":{\"sha1\":\"123\",\"md5\":\"456\",\"sha256\":\"789\"},\"size\":111,\"links\":[],\"unknownProperty\": \"test\"}";
// Test // Test
DdiArtifact ddiArtifact = mapper.readValue(serializedDdiArtifact, DdiArtifact.class); final DdiArtifact ddiArtifact = OBJECT_MAPPER.readValue(serializedDdiArtifact, DdiArtifact.class);
assertThat(ddiArtifact.getFilename()).isEqualTo("test.file"); assertThat(ddiArtifact.getFilename()).isEqualTo("test.file");
assertThat(ddiArtifact.getSize()).isEqualTo(111); assertThat(ddiArtifact.getSize()).isEqualTo(111);
assertThat(ddiArtifact.getHashes().getSha1()).isEqualTo("123"); assertThat(ddiArtifact.getHashes().getSha1()).isEqualTo("123");
@@ -76,10 +74,10 @@ public class DdiArtifactTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiArtifact = "{\"filename\": [\"test.file\"],\"hashes\":{\"sha1\":\"123\",\"md5\":\"456\",\"sha256\":\"789\"},\"size\":111,\"links\":[]}"; final String serializedDdiArtifact = "{\"filename\": [\"test.file\"],\"hashes\":{\"sha1\":\"123\",\"md5\":\"456\",\"sha256\":\"789\"},\"size\":111,\"links\":[]}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiArtifact, DdiArtifact.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiArtifact, DdiArtifact.class));
} }
} }

View File

@@ -29,19 +29,19 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiCancelActionToStopTest { public class DdiCancelActionToStopTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
String stopId = "1234"; final String stopId = "1234";
DdiCancelActionToStop ddiCancelActionToStop = new DdiCancelActionToStop(stopId); final DdiCancelActionToStop ddiCancelActionToStop = new DdiCancelActionToStop(stopId);
// Test
String serializedDdiCancelActionToStop = mapper.writeValueAsString(ddiCancelActionToStop);
DdiCancelActionToStop deserializedDdiCancelActionToStop = mapper.readValue(serializedDdiCancelActionToStop,
DdiCancelActionToStop.class);
// Test
final String serializedDdiCancelActionToStop = OBJECT_MAPPER.writeValueAsString(ddiCancelActionToStop);
final DdiCancelActionToStop deserializedDdiCancelActionToStop = OBJECT_MAPPER.readValue(
serializedDdiCancelActionToStop, DdiCancelActionToStop.class);
assertThat(serializedDdiCancelActionToStop).contains(stopId); assertThat(serializedDdiCancelActionToStop).contains(stopId);
assertThat(deserializedDdiCancelActionToStop.getStopId()).isEqualTo(stopId); assertThat(deserializedDdiCancelActionToStop.getStopId()).isEqualTo(stopId);
} }
@@ -50,12 +50,11 @@ public class DdiCancelActionToStopTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiCancelActionToStop = "{\"stopId\":\"12345\",\"unknownProperty\":\"test\"}"; final String serializedDdiCancelActionToStop = "{\"stopId\":\"12345\",\"unknownProperty\":\"test\"}";
// Test // Test
DdiCancelActionToStop ddiCancelActionToStop = mapper.readValue(serializedDdiCancelActionToStop, final DdiCancelActionToStop ddiCancelActionToStop = OBJECT_MAPPER.readValue(
DdiCancelActionToStop.class); serializedDdiCancelActionToStop, DdiCancelActionToStop.class);
assertThat(ddiCancelActionToStop.getStopId()).contains("12345"); assertThat(ddiCancelActionToStop.getStopId()).contains("12345");
} }
@@ -63,10 +62,10 @@ public class DdiCancelActionToStopTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiCancelActionToStop = "{\"stopId\": [\"12345\"]}"; final String serializedDdiCancelActionToStop = "{\"stopId\": [\"12345\"]}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiCancelActionToStop, DdiCancelActionToStop.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiCancelActionToStop, DdiCancelActionToStop.class));
} }
} }

View File

@@ -29,20 +29,19 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiCancelTest { public class DdiCancelTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
String ddiCancelId = "1234"; final String ddiCancelId = "1234";
DdiCancelActionToStop ddiCancelActionToStop = new DdiCancelActionToStop("1234"); final DdiCancelActionToStop ddiCancelActionToStop = new DdiCancelActionToStop("1234");
DdiCancel ddiCancel = new DdiCancel(ddiCancelId, ddiCancelActionToStop); final DdiCancel ddiCancel = new DdiCancel(ddiCancelId, ddiCancelActionToStop);
// Test // Test
String serializedDdiCancel = mapper.writeValueAsString(ddiCancel); final String serializedDdiCancel = OBJECT_MAPPER.writeValueAsString(ddiCancel);
DdiCancel deserializedDdiCancel = mapper.readValue(serializedDdiCancel, DdiCancel.class); final DdiCancel deserializedDdiCancel = OBJECT_MAPPER.readValue(serializedDdiCancel, DdiCancel.class);
assertThat(serializedDdiCancel).contains(ddiCancelId, ddiCancelActionToStop.getStopId()); assertThat(serializedDdiCancel).contains(ddiCancelId, ddiCancelActionToStop.getStopId());
assertThat(deserializedDdiCancel.getId()).isEqualTo(ddiCancelId); assertThat(deserializedDdiCancel.getId()).isEqualTo(ddiCancelId);
assertThat(deserializedDdiCancel.getCancelAction().getStopId()).isEqualTo(ddiCancelActionToStop.getStopId()); assertThat(deserializedDdiCancel.getCancelAction().getStopId()).isEqualTo(ddiCancelActionToStop.getStopId());
@@ -52,11 +51,10 @@ public class DdiCancelTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiCancel = "{\"id\":\"1234\",\"cancelAction\":{\"stopId\":\"1234\"}, \"unknownProperty\": \"test\"}"; final String serializedDdiCancel = "{\"id\":\"1234\",\"cancelAction\":{\"stopId\":\"1234\"}, \"unknownProperty\": \"test\"}";
// Test // Test
DdiCancel ddiCancel = mapper.readValue(serializedDdiCancel, DdiCancel.class); final DdiCancel ddiCancel = OBJECT_MAPPER.readValue(serializedDdiCancel, DdiCancel.class);
assertThat(ddiCancel.getId()).isEqualTo("1234"); assertThat(ddiCancel.getId()).isEqualTo("1234");
assertThat(ddiCancel.getCancelAction().getStopId()).matches("1234"); assertThat(ddiCancel.getCancelAction().getStopId()).matches("1234");
} }
@@ -65,10 +63,10 @@ public class DdiCancelTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiCancel = "{\"id\":[\"1234\"],\"cancelAction\":{\"stopId\":\"1234\"}}"; final String serializedDdiCancel = "{\"id\":[\"1234\"],\"cancelAction\":{\"stopId\":\"1234\"}}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiCancel, DdiCancel.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiCancel, DdiCancel.class));
} }
} }

View File

@@ -31,7 +31,7 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiChunkTest { public class DdiChunkTest {
private final ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
@@ -44,9 +44,8 @@ public class DdiChunkTest {
final DdiChunk ddiChunk = new DdiChunk(part, version, name, null, dummyArtifacts, null); final DdiChunk ddiChunk = new DdiChunk(part, version, name, null, dummyArtifacts, null);
// Test // Test
final String serializedDdiChunk = mapper.writeValueAsString(ddiChunk); final String serializedDdiChunk = OBJECT_MAPPER.writeValueAsString(ddiChunk);
final DdiChunk deserializedDdiChunk = mapper.readValue(serializedDdiChunk, DdiChunk.class); final DdiChunk deserializedDdiChunk = OBJECT_MAPPER.readValue(serializedDdiChunk, DdiChunk.class);
assertThat(serializedDdiChunk).contains(part, version, name); assertThat(serializedDdiChunk).contains(part, version, name);
assertThat(deserializedDdiChunk.getPart()).isEqualTo(part); assertThat(deserializedDdiChunk.getPart()).isEqualTo(part);
assertThat(deserializedDdiChunk.getVersion()).isEqualTo(version); assertThat(deserializedDdiChunk.getVersion()).isEqualTo(version);
@@ -61,8 +60,7 @@ public class DdiChunkTest {
final String serializedDdiChunk = "{\"part\":\"1234\",\"version\":\"1.0\",\"name\":\"Dummy-Artifact\",\"artifacts\":[],\"unknownProperty\":\"test\"}"; final String serializedDdiChunk = "{\"part\":\"1234\",\"version\":\"1.0\",\"name\":\"Dummy-Artifact\",\"artifacts\":[],\"unknownProperty\":\"test\"}";
// Test // Test
final DdiChunk ddiChunk = mapper.readValue(serializedDdiChunk, DdiChunk.class); final DdiChunk ddiChunk = OBJECT_MAPPER.readValue(serializedDdiChunk, DdiChunk.class);
assertThat(ddiChunk.getPart()).isEqualTo("1234"); assertThat(ddiChunk.getPart()).isEqualTo("1234");
assertThat(ddiChunk.getVersion()).isEqualTo("1.0"); assertThat(ddiChunk.getVersion()).isEqualTo("1.0");
assertThat(ddiChunk.getName()).isEqualTo("Dummy-Artifact"); assertThat(ddiChunk.getName()).isEqualTo("Dummy-Artifact");
@@ -77,6 +75,6 @@ public class DdiChunkTest {
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class) assertThatExceptionOfType(MismatchedInputException.class)
.isThrownBy(() -> mapper.readValue(serializedDdiChunk, DdiChunk.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiChunk, DdiChunk.class));
} }
} }

View File

@@ -31,34 +31,31 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiConfigDataTest { public class DdiConfigDataTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
Map<String, String> data = new HashMap<>(); final Map<String, String> data = new HashMap<>();
data.put("test", "data"); data.put("test", "data");
DdiConfigData ddiConfigData = new DdiConfigData(data, DdiUpdateMode.REPLACE); final DdiConfigData ddiConfigData = new DdiConfigData(data, DdiUpdateMode.REPLACE);
// Test // Test
String serializedDdiConfigData = mapper.writeValueAsString(ddiConfigData); final String serializedDdiConfigData = OBJECT_MAPPER.writeValueAsString(ddiConfigData);
DdiConfigData deserializedDdiConfigData = mapper.readValue(serializedDdiConfigData, DdiConfigData.class); final DdiConfigData deserializedDdiConfigData = OBJECT_MAPPER.readValue(serializedDdiConfigData, DdiConfigData.class);
assertThat(serializedDdiConfigData).contains("test", "data"); assertThat(serializedDdiConfigData).contains("test", "data");
assertThat(deserializedDdiConfigData.getMode()).isEqualTo(DdiUpdateMode.REPLACE); assertThat(deserializedDdiConfigData.getMode()).isEqualTo(DdiUpdateMode.REPLACE);
} }
@Test @Test
@Description("Verify the correct deserialization of a model with an additional unknown property") @Description("Verify the correct deserialization of a model with an additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiConfigData = "{\"data\":{\"test\":\"data\"},\"mode\":\"replace\",\"unknownProperty\":\"test\"}"; final String serializedDdiConfigData = "{\"data\":{\"test\":\"data\"},\"mode\":\"replace\",\"unknownProperty\":\"test\"}";
// Test // Test
DdiConfigData ddiConfigData = mapper.readValue(serializedDdiConfigData, DdiConfigData.class); final DdiConfigData ddiConfigData = OBJECT_MAPPER.readValue(serializedDdiConfigData, DdiConfigData.class);
assertThat(ddiConfigData.getMode()).isEqualTo(DdiUpdateMode.REPLACE); assertThat(ddiConfigData.getMode()).isEqualTo(DdiUpdateMode.REPLACE);
} }
@@ -66,11 +63,11 @@ public class DdiConfigDataTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiConfigData = "{\"data\":{\"test\":\"data\"},\"mode\":[\"replace\"],\"unknownProperty\":\"test\"}"; final String serializedDdiConfigData = "{\"data\":{\"test\":\"data\"},\"mode\":[\"replace\"],\"unknownProperty\":\"test\"}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiConfigData, DdiConfigData.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiConfigData, DdiConfigData.class));
} }
@Test @Test
@@ -88,7 +85,7 @@ public class DdiConfigDataTest {
+ "\"details\":[]},\"data\":{\"test\":\"data\"},\"mode\":\"replace\"}"; + "\"details\":[]},\"data\":{\"test\":\"data\"},\"mode\":\"replace\"}";
// Test // Test
DdiConfigData ddiConfigData = mapper.readValue(serializedDdiConfigData, DdiConfigData.class); DdiConfigData ddiConfigData = OBJECT_MAPPER.readValue(serializedDdiConfigData, DdiConfigData.class);
assertThat(ddiConfigData.getMode()).isEqualTo(DdiUpdateMode.REPLACE); assertThat(ddiConfigData.getMode()).isEqualTo(DdiUpdateMode.REPLACE);
} }

View File

@@ -29,19 +29,18 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiConfigTest { public class DdiConfigTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
DdiPolling ddiPolling = new DdiPolling("10"); final DdiPolling ddiPolling = new DdiPolling("10");
DdiConfig ddiConfig = new DdiConfig(ddiPolling); final DdiConfig ddiConfig = new DdiConfig(ddiPolling);
// Test // Test
String serializedDdiConfig = mapper.writeValueAsString(ddiConfig); final String serializedDdiConfig = OBJECT_MAPPER.writeValueAsString(ddiConfig);
DdiConfig deserializedDdiConfig = mapper.readValue(serializedDdiConfig, DdiConfig.class); final DdiConfig deserializedDdiConfig = OBJECT_MAPPER.readValue(serializedDdiConfig, DdiConfig.class);
assertThat(serializedDdiConfig).contains("10"); assertThat(serializedDdiConfig).contains("10");
assertThat(deserializedDdiConfig.getPolling().getSleep()).isEqualTo("10"); assertThat(deserializedDdiConfig.getPolling().getSleep()).isEqualTo("10");
} }
@@ -50,11 +49,10 @@ public class DdiConfigTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiConfig = "{\"polling\":{\"sleep\":\"123\"},\"unknownProperty\":\"test\"}"; final String serializedDdiConfig = "{\"polling\":{\"sleep\":\"123\"},\"unknownProperty\":\"test\"}";
// Test // Test
DdiConfig ddiConfig = mapper.readValue(serializedDdiConfig, DdiConfig.class); final DdiConfig ddiConfig = OBJECT_MAPPER.readValue(serializedDdiConfig, DdiConfig.class);
assertThat(ddiConfig.getPolling().getSleep()).isEqualTo("123"); assertThat(ddiConfig.getPolling().getSleep()).isEqualTo("123");
} }
@@ -62,10 +60,10 @@ public class DdiConfigTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiConfig = "{\"polling\":{\"sleep\":[\"10\"]}}"; final String serializedDdiConfig = "{\"polling\":{\"sleep\":[\"10\"]}}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiConfig, DdiConfig.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiConfig, DdiConfig.class));
} }
} }

View File

@@ -17,8 +17,8 @@ import static org.eclipse.hawkbit.ddi.json.model.DdiDeployment.HandlingType.ATTE
import static org.eclipse.hawkbit.ddi.json.model.DdiDeployment.HandlingType.FORCED; import static org.eclipse.hawkbit.ddi.json.model.DdiDeployment.HandlingType.FORCED;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.MismatchedInputException; import com.fasterxml.jackson.databind.exc.MismatchedInputException;
@@ -43,10 +43,8 @@ class DdiConfirmationBaseTest {
final String id = "1234"; final String id = "1234";
final DdiDeployment ddiDeployment = new DdiDeployment(FORCED, ATTEMPT, Collections.emptyList(), AVAILABLE); final DdiDeployment ddiDeployment = new DdiDeployment(FORCED, ATTEMPT, Collections.emptyList(), AVAILABLE);
final String actionStatus = "TestAction"; final String actionStatus = "TestAction";
final DdiActionHistory ddiActionHistory = new DdiActionHistory(actionStatus, final DdiActionHistory ddiActionHistory = new DdiActionHistory(actionStatus, List.of("Action status message 1", "Action status message 2"));
Arrays.asList("Action status message 1", "Action status message 2")); final DdiConfirmationBaseAction ddiConfirmationBaseAction = new DdiConfirmationBaseAction(id, ddiDeployment, ddiActionHistory);
final DdiConfirmationBaseAction ddiConfirmationBaseAction = new DdiConfirmationBaseAction(id, ddiDeployment,
ddiActionHistory);
// Test // Test
String serializedDdiConfirmationBase = OBJECT_MAPPER.writeValueAsString(ddiConfirmationBaseAction); String serializedDdiConfirmationBase = OBJECT_MAPPER.writeValueAsString(ddiConfirmationBaseAction);

View File

@@ -29,22 +29,19 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiControllerBaseTest { public class DdiControllerBaseTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
// Setup final DdiPolling ddiPolling = new DdiPolling("10");
DdiPolling ddiPolling = new DdiPolling("10"); final DdiConfig ddiConfig = new DdiConfig(ddiPolling);
DdiConfig ddiConfig = new DdiConfig(ddiPolling); final DdiControllerBase ddiControllerBase = new DdiControllerBase(ddiConfig);
DdiControllerBase ddiControllerBase = new DdiControllerBase(ddiConfig);
// Test // Test
String serializedDdiControllerBase = mapper.writeValueAsString(ddiControllerBase); final String serializedDdiControllerBase = OBJECT_MAPPER.writeValueAsString(ddiControllerBase);
DdiControllerBase deserializedDdiControllerBase = mapper.readValue(serializedDdiControllerBase, final DdiControllerBase deserializedDdiControllerBase = OBJECT_MAPPER.readValue(serializedDdiControllerBase, DdiControllerBase.class);
DdiControllerBase.class);
assertThat(serializedDdiControllerBase).contains(ddiPolling.getSleep()); assertThat(serializedDdiControllerBase).contains(ddiPolling.getSleep());
assertThat(deserializedDdiControllerBase.getConfig().getPolling().getSleep()).isEqualTo(ddiPolling.getSleep()); assertThat(deserializedDdiControllerBase.getConfig().getPolling().getSleep()).isEqualTo(ddiPolling.getSleep());
} }
@@ -53,11 +50,10 @@ public class DdiControllerBaseTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiControllerBase = "{\"config\":{\"polling\":{\"sleep\":\"123\"}},\"links\":[],\"unknownProperty\":\"test\"}"; final String serializedDdiControllerBase = "{\"config\":{\"polling\":{\"sleep\":\"123\"}},\"links\":[],\"unknownProperty\":\"test\"}";
// Test // Test
DdiControllerBase ddiControllerBase = mapper.readValue(serializedDdiControllerBase, DdiControllerBase.class); final DdiControllerBase ddiControllerBase = OBJECT_MAPPER.readValue(serializedDdiControllerBase, DdiControllerBase.class);
assertThat(ddiControllerBase.getConfig().getPolling().getSleep()).isEqualTo("123"); assertThat(ddiControllerBase.getConfig().getPolling().getSleep()).isEqualTo("123");
} }
@@ -65,10 +61,10 @@ public class DdiControllerBaseTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiControllerBase = "{\"config\":{\"polling\":{\"sleep\":[\"123\"]}},\"links\":[],\"unknownProperty\":\"test\"}"; final String serializedDdiControllerBase = "{\"config\":{\"polling\":{\"sleep\":[\"123\"]}},\"links\":[],\"unknownProperty\":\"test\"}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiControllerBase, DdiControllerBase.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiControllerBase, DdiControllerBase.class));
} }
} }

View File

@@ -19,6 +19,7 @@ import static org.eclipse.hawkbit.ddi.json.model.DdiDeployment.HandlingType.FORC
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.MismatchedInputException; import com.fasterxml.jackson.databind.exc.MismatchedInputException;
@@ -34,30 +35,25 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiDeploymentBaseTest { public class DdiDeploymentBaseTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
String id = "1234"; final String id = "1234";
DdiDeployment ddiDeployment = new DdiDeployment(FORCED, ATTEMPT, Collections.emptyList(), AVAILABLE); final DdiDeployment ddiDeployment = new DdiDeployment(FORCED, ATTEMPT, Collections.emptyList(), AVAILABLE);
String actionStatus = "TestAction"; final String actionStatus = "TestAction";
DdiActionHistory ddiActionHistory = new DdiActionHistory(actionStatus, final DdiActionHistory ddiActionHistory = new DdiActionHistory(actionStatus, List.of("Action status message 1", "Action status message 2"));
Arrays.asList("Action status message 1", "Action status message 2")); final DdiDeploymentBase ddiDeploymentBase = new DdiDeploymentBase(id, ddiDeployment, ddiActionHistory);
DdiDeploymentBase ddiDeploymentBase = new DdiDeploymentBase(id, ddiDeployment, ddiActionHistory);
// Test // Test
String serializedDdiDeploymentBase = mapper.writeValueAsString(ddiDeploymentBase); final String serializedDdiDeploymentBase = OBJECT_MAPPER.writeValueAsString(ddiDeploymentBase);
DdiDeploymentBase deserializedDdiDeploymentBase = mapper.readValue(serializedDdiDeploymentBase, final DdiDeploymentBase deserializedDdiDeploymentBase = OBJECT_MAPPER.readValue(serializedDdiDeploymentBase, DdiDeploymentBase.class);
DdiDeploymentBase.class); assertThat(serializedDdiDeploymentBase).contains(id, FORCED.getName(), ATTEMPT.getName(), AVAILABLE.getStatus(), actionStatus);
assertThat(serializedDdiDeploymentBase).contains(id, FORCED.getName(), ATTEMPT.getName(), AVAILABLE.getStatus(),
actionStatus);
assertThat(deserializedDdiDeploymentBase.getDeployment().getDownload()).isEqualTo(ddiDeployment.getDownload()); assertThat(deserializedDdiDeploymentBase.getDeployment().getDownload()).isEqualTo(ddiDeployment.getDownload());
assertThat(deserializedDdiDeploymentBase.getDeployment().getUpdate()).isEqualTo(ddiDeployment.getUpdate()); assertThat(deserializedDdiDeploymentBase.getDeployment().getUpdate()).isEqualTo(ddiDeployment.getUpdate());
assertThat(deserializedDdiDeploymentBase.getDeployment().getMaintenanceWindow()).isEqualTo( assertThat(deserializedDdiDeploymentBase.getDeployment().getMaintenanceWindow()).isEqualTo(ddiDeployment.getMaintenanceWindow());
ddiDeployment.getMaintenanceWindow());
assertThat(deserializedDdiDeploymentBase.getActionHistory().toString()).isEqualTo(ddiActionHistory.toString()); assertThat(deserializedDdiDeploymentBase.getActionHistory().toString()).isEqualTo(ddiActionHistory.toString());
} }
@@ -65,31 +61,29 @@ public class DdiDeploymentBaseTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiDeploymentBase = "{\"id\":\"1234\",\"deployment\":{\"download\":\"forced\"," final String serializedDdiDeploymentBase = "{\"id\":\"1234\",\"deployment\":{\"download\":\"forced\"," +
+ "\"update\":\"attempt\",\"maintenanceWindow\":\"available\",\"chunks\":[]}," "\"update\":\"attempt\",\"maintenanceWindow\":\"available\",\"chunks\":[]}," +
+ "\"actionHistory\":{\"status\":\"TestAction\",\"messages\":[\"Action status message 1\"," "\"actionHistory\":{\"status\":\"TestAction\",\"messages\":[\"Action status message 1\"," +
+ "\"Action status message 2\"]},\"links\":[],\"unknownProperty\":\"test\"}"; "\"Action status message 2\"]},\"links\":[],\"unknownProperty\":\"test\"}";
// Test // Test
DdiDeploymentBase ddiDeploymentBase = mapper.readValue(serializedDdiDeploymentBase, DdiDeploymentBase.class); final DdiDeploymentBase ddiDeploymentBase = OBJECT_MAPPER.readValue(serializedDdiDeploymentBase, DdiDeploymentBase.class);
assertThat(ddiDeploymentBase.getDeployment().getDownload().getName()).isEqualTo(FORCED.getName()); assertThat(ddiDeploymentBase.getDeployment().getDownload().getName()).isEqualTo(FORCED.getName());
assertThat(ddiDeploymentBase.getDeployment().getUpdate().getName()).isEqualTo(ATTEMPT.getName()); assertThat(ddiDeploymentBase.getDeployment().getUpdate().getName()).isEqualTo(ATTEMPT.getName());
assertThat(ddiDeploymentBase.getDeployment().getMaintenanceWindow().getStatus()).isEqualTo( assertThat(ddiDeploymentBase.getDeployment().getMaintenanceWindow().getStatus()).isEqualTo(AVAILABLE.getStatus());
AVAILABLE.getStatus());
} }
@Test @Test
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiDeploymentBase = "{\"id\":[\"1234\"],\"deployment\":{\"download\":\"forced\"," final String serializedDdiDeploymentBase = "{\"id\":[\"1234\"],\"deployment\":{\"download\":\"forced\"," +
+ "\"update\":\"attempt\",\"maintenanceWindow\":\"available\",\"chunks\":[]}," "\"update\":\"attempt\",\"maintenanceWindow\":\"available\",\"chunks\":[]}," +
+ "\"actionHistory\":{\"status\":\"TestAction\",\"messages\":[\"Action status message 1\"," "\"actionHistory\":{\"status\":\"TestAction\",\"messages\":[\"Action status message 1\"," +
+ "\"Action status message 2\"]},\"links\":[]}"; "\"Action status message 2\"]},\"links\":[]}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiDeploymentBase, DdiDeploymentBase.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiDeploymentBase, DdiDeploymentBase.class));
} }
} }

View File

@@ -33,36 +33,33 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiDeploymentTest { public class DdiDeploymentTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
DdiDeployment ddiDeployment = new DdiDeployment(FORCED, ATTEMPT, Collections.emptyList(), AVAILABLE); final DdiDeployment ddiDeployment = new DdiDeployment(FORCED, ATTEMPT, Collections.emptyList(), AVAILABLE);
// Test // Test
String serializedDdiDeployment = mapper.writeValueAsString(ddiDeployment); final String serializedDdiDeployment = OBJECT_MAPPER.writeValueAsString(ddiDeployment);
DdiDeployment deserializedDdiDeployment = mapper.readValue(serializedDdiDeployment, DdiDeployment.class); final DdiDeployment deserializedDdiDeployment = OBJECT_MAPPER.readValue(serializedDdiDeployment, DdiDeployment.class);
assertThat(serializedDdiDeployment).contains(ddiDeployment.getDownload().getName(), assertThat(serializedDdiDeployment).contains(ddiDeployment.getDownload().getName(), ddiDeployment.getMaintenanceWindow().getStatus());
ddiDeployment.getMaintenanceWindow().getStatus());
assertThat(deserializedDdiDeployment.getDownload().getName()).isEqualTo(ddiDeployment.getDownload().getName()); assertThat(deserializedDdiDeployment.getDownload().getName()).isEqualTo(ddiDeployment.getDownload().getName());
assertThat(deserializedDdiDeployment.getUpdate().getName()).isEqualTo(ddiDeployment.getUpdate().getName()); assertThat(deserializedDdiDeployment.getUpdate().getName()).isEqualTo(ddiDeployment.getUpdate().getName());
assertThat(deserializedDdiDeployment.getMaintenanceWindow().getStatus()).isEqualTo( assertThat(deserializedDdiDeployment.getMaintenanceWindow().getStatus()).isEqualTo(ddiDeployment.getMaintenanceWindow().getStatus());
ddiDeployment.getMaintenanceWindow().getStatus());
} }
@Test @Test
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiDeployment = "{\"download\":\"forced\",\"update\":\"attempt\", " final String serializedDdiDeployment = "{\"download\":\"forced\",\"update\":\"attempt\", " +
+ "\"maintenanceWindow\":\"available\",\"chunks\":[],\"unknownProperty\":\"test\"}"; "\"maintenanceWindow\":\"available\",\"chunks\":[],\"unknownProperty\":\"test\"}";
// Test // Test
DdiDeployment ddiDeployment = mapper.readValue(serializedDdiDeployment, DdiDeployment.class); final DdiDeployment ddiDeployment = OBJECT_MAPPER.readValue(serializedDdiDeployment, DdiDeployment.class);
assertThat(ddiDeployment.getDownload().getName()).isEqualTo(FORCED.getName()); assertThat(ddiDeployment.getDownload().getName()).isEqualTo(FORCED.getName());
assertThat(ddiDeployment.getUpdate().getName()).isEqualTo(ATTEMPT.getName()); assertThat(ddiDeployment.getUpdate().getName()).isEqualTo(ATTEMPT.getName());
assertThat(ddiDeployment.getMaintenanceWindow().getStatus()).isEqualTo(AVAILABLE.getStatus()); assertThat(ddiDeployment.getMaintenanceWindow().getStatus()).isEqualTo(AVAILABLE.getStatus());
@@ -72,11 +69,11 @@ public class DdiDeploymentTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiDeployment = "{\"download\":[\"forced\"],\"update\":\"attempt\", " final String serializedDdiDeployment = "{\"download\":[\"forced\"],\"update\":\"attempt\", " +
+ "\"maintenanceWindow\":\"available\",\"chunks\":[]}"; "\"maintenanceWindow\":\"available\",\"chunks\":[]}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiDeployment, DdiDeployment.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiDeployment, DdiDeployment.class));
} }
} }

View File

@@ -29,20 +29,19 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiMetadataTest { public class DdiMetadataTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
String key = "testKey"; final String key = "testKey";
String value = "testValue"; final String value = "testValue";
DdiMetadata ddiMetadata = new DdiMetadata(key, value); final DdiMetadata ddiMetadata = new DdiMetadata(key, value);
// Test // Test
String serializedDdiMetadata = mapper.writeValueAsString(ddiMetadata); final String serializedDdiMetadata = OBJECT_MAPPER.writeValueAsString(ddiMetadata);
DdiMetadata deserializedDdiMetadata = mapper.readValue(serializedDdiMetadata, DdiMetadata.class); final DdiMetadata deserializedDdiMetadata = OBJECT_MAPPER.readValue(serializedDdiMetadata, DdiMetadata.class);
assertThat(serializedDdiMetadata).contains(key, value); assertThat(serializedDdiMetadata).contains(key, value);
assertThat(deserializedDdiMetadata.getKey()).isEqualTo(ddiMetadata.getKey()); assertThat(deserializedDdiMetadata.getKey()).isEqualTo(ddiMetadata.getKey());
assertThat(deserializedDdiMetadata.getValue()).isEqualTo(ddiMetadata.getValue()); assertThat(deserializedDdiMetadata.getValue()).isEqualTo(ddiMetadata.getValue());
@@ -52,11 +51,10 @@ public class DdiMetadataTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiMetadata = "{\"key\":\"testKey\",\"value\":\"testValue\",\"unknownProperty\":\"test\"}"; final String serializedDdiMetadata = "{\"key\":\"testKey\",\"value\":\"testValue\",\"unknownProperty\":\"test\"}";
// Test // Test
DdiMetadata ddiMetadata = mapper.readValue(serializedDdiMetadata, DdiMetadata.class); final DdiMetadata ddiMetadata = OBJECT_MAPPER.readValue(serializedDdiMetadata, DdiMetadata.class);
assertThat(ddiMetadata.getKey()).isEqualTo("testKey"); assertThat(ddiMetadata.getKey()).isEqualTo("testKey");
assertThat(ddiMetadata.getValue()).isEqualTo("testValue"); assertThat(ddiMetadata.getValue()).isEqualTo("testValue");
} }
@@ -65,10 +63,10 @@ public class DdiMetadataTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiMetadata = "{\"key\":[\"testKey\"],\"value\":\"testValue\"}"; final String serializedDdiMetadata = "{\"key\":[\"testKey\"],\"value\":\"testValue\"}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiMetadata, DdiMetadata.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiMetadata, DdiMetadata.class));
} }
} }

View File

@@ -29,18 +29,17 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiPollingTest { public class DdiPollingTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
DdiPolling ddiPolling = new DdiPolling("10"); final DdiPolling ddiPolling = new DdiPolling("10");
// Test // Test
String serializedDdiPolling = mapper.writeValueAsString(ddiPolling); final String serializedDdiPolling = OBJECT_MAPPER.writeValueAsString(ddiPolling);
DdiPolling deserializedDdiPolling = mapper.readValue(serializedDdiPolling, DdiPolling.class); final DdiPolling deserializedDdiPolling = OBJECT_MAPPER.readValue(serializedDdiPolling, DdiPolling.class);
assertThat(serializedDdiPolling).contains(ddiPolling.getSleep()); assertThat(serializedDdiPolling).contains(ddiPolling.getSleep());
assertThat(deserializedDdiPolling.getSleep()).isEqualTo(ddiPolling.getSleep()); assertThat(deserializedDdiPolling.getSleep()).isEqualTo(ddiPolling.getSleep());
} }
@@ -49,11 +48,10 @@ public class DdiPollingTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiPolling = "{\"sleep\":\"10\",\"unknownProperty\":\"test\"}"; final String serializedDdiPolling = "{\"sleep\":\"10\",\"unknownProperty\":\"test\"}";
// Test // Test
DdiPolling ddiPolling = mapper.readValue(serializedDdiPolling, DdiPolling.class); final DdiPolling ddiPolling = OBJECT_MAPPER.readValue(serializedDdiPolling, DdiPolling.class);
assertThat(ddiPolling.getSleep()).isEqualTo("10"); assertThat(ddiPolling.getSleep()).isEqualTo("10");
} }
@@ -61,10 +59,10 @@ public class DdiPollingTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiPolling = "{\"sleep\":[\"10\"]}"; final String serializedDdiPolling = "{\"sleep\":[\"10\"]}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiPolling, DdiPolling.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiPolling, DdiPolling.class));
} }
} }

View File

@@ -29,18 +29,17 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiProgressTest { public class DdiProgressTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
DdiProgress ddiProgress = new DdiProgress(30, 100); final DdiProgress ddiProgress = new DdiProgress(30, 100);
// Test // Test
String serializedDdiProgress = mapper.writeValueAsString(ddiProgress); final String serializedDdiProgress = OBJECT_MAPPER.writeValueAsString(ddiProgress);
DdiProgress deserializedDdiProgress = mapper.readValue(serializedDdiProgress, DdiProgress.class); final DdiProgress deserializedDdiProgress = OBJECT_MAPPER.readValue(serializedDdiProgress, DdiProgress.class);
assertThat(serializedDdiProgress).contains(ddiProgress.getCnt().toString(), ddiProgress.getOf().toString()); assertThat(serializedDdiProgress).contains(ddiProgress.getCnt().toString(), ddiProgress.getOf().toString());
assertThat(deserializedDdiProgress.getCnt()).isEqualTo(ddiProgress.getCnt()); assertThat(deserializedDdiProgress.getCnt()).isEqualTo(ddiProgress.getCnt());
assertThat(deserializedDdiProgress.getOf()).isEqualTo(ddiProgress.getOf()); assertThat(deserializedDdiProgress.getOf()).isEqualTo(ddiProgress.getOf());
@@ -50,11 +49,10 @@ public class DdiProgressTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiProgress = "{\"cnt\":30,\"of\":100,\"unknownProperty\":\"test\"}"; final String serializedDdiProgress = "{\"cnt\":30,\"of\":100,\"unknownProperty\":\"test\"}";
// Test // Test
DdiProgress ddiProgress = mapper.readValue(serializedDdiProgress, DdiProgress.class); final DdiProgress ddiProgress = OBJECT_MAPPER.readValue(serializedDdiProgress, DdiProgress.class);
assertThat(ddiProgress.getCnt()).isEqualTo(30); assertThat(ddiProgress.getCnt()).isEqualTo(30);
assertThat(ddiProgress.getOf()).isEqualTo(100); assertThat(ddiProgress.getOf()).isEqualTo(100);
} }
@@ -63,10 +61,10 @@ public class DdiProgressTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiProgress = "{\"cnt\":[30],\"of\":100}"; final String serializedDdiProgress = "{\"cnt\":[30],\"of\":100}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiProgress, DdiProgress.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiProgress, DdiProgress.class));
} }
} }

View File

@@ -30,21 +30,19 @@ import org.junit.jupiter.api.Test;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiResultTest { public class DdiResultTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test @Test
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject() throws IOException { public void shouldSerializeAndDeserializeObject() throws IOException {
// Setup // Setup
DdiProgress ddiProgress = new DdiProgress(30, 100); final DdiProgress ddiProgress = new DdiProgress(30, 100);
DdiResult ddiResult = new DdiResult(NONE, ddiProgress); final DdiResult ddiResult = new DdiResult(NONE, ddiProgress);
// Test // Test
String serializedDdiResult = mapper.writeValueAsString(ddiResult); final String serializedDdiResult = OBJECT_MAPPER.writeValueAsString(ddiResult);
DdiResult deserializedDdiResult = mapper.readValue(serializedDdiResult, DdiResult.class); final DdiResult deserializedDdiResult = OBJECT_MAPPER.readValue(serializedDdiResult, DdiResult.class);
assertThat(serializedDdiResult).contains(NONE.getName(), ddiProgress.getCnt().toString(), ddiProgress.getOf().toString());
assertThat(serializedDdiResult).contains(NONE.getName(), ddiProgress.getCnt().toString(),
ddiProgress.getOf().toString());
assertThat(deserializedDdiResult.getFinished()).isEqualTo(ddiResult.getFinished()); assertThat(deserializedDdiResult.getFinished()).isEqualTo(ddiResult.getFinished());
assertThat(deserializedDdiResult.getProgress().getCnt()).isEqualTo(ddiProgress.getCnt()); assertThat(deserializedDdiResult.getProgress().getCnt()).isEqualTo(ddiProgress.getCnt());
assertThat(deserializedDdiResult.getProgress().getOf()).isEqualTo(ddiProgress.getOf()); assertThat(deserializedDdiResult.getProgress().getOf()).isEqualTo(ddiProgress.getOf());
@@ -54,11 +52,10 @@ public class DdiResultTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
String serializedDdiResult = "{\"finished\":\"none\",\"progress\":{\"cnt\":30,\"of\":100},\"unknownProperty\":\"test\"}"; final String serializedDdiResult = "{\"finished\":\"none\",\"progress\":{\"cnt\":30,\"of\":100},\"unknownProperty\":\"test\"}";
// Test // Test
DdiResult ddiResult = mapper.readValue(serializedDdiResult, DdiResult.class); final DdiResult ddiResult = OBJECT_MAPPER.readValue(serializedDdiResult, DdiResult.class);
assertThat(ddiResult.getFinished()).isEqualTo(NONE); assertThat(ddiResult.getFinished()).isEqualTo(NONE);
assertThat(ddiResult.getProgress().getCnt()).isEqualTo(30); assertThat(ddiResult.getProgress().getCnt()).isEqualTo(30);
assertThat(ddiResult.getProgress().getOf()).isEqualTo(100); assertThat(ddiResult.getProgress().getOf()).isEqualTo(100);
@@ -68,10 +65,10 @@ public class DdiResultTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiResult = "{\"finished\":[\"none\"],\"progress\":{\"cnt\":30,\"of\":100}}"; final String serializedDdiResult = "{\"finished\":[\"none\"],\"progress\":{\"cnt\":30,\"of\":100}}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiResult, DdiResult.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiResult, DdiResult.class));
} }
} }

View File

@@ -36,24 +36,21 @@ import org.junit.jupiter.params.provider.MethodSource;
@Story("Serializability of DDI api Models") @Story("Serializability of DDI api Models")
public class DdiStatusTest { public class DdiStatusTest {
private ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@ParameterizedTest @ParameterizedTest
@MethodSource("ddiStatusPossibilities") @MethodSource("ddiStatusPossibilities")
@Description("Verify the correct serialization and deserialization of the model") @Description("Verify the correct serialization and deserialization of the model")
public void shouldSerializeAndDeserializeObject(final DdiResult ddiResult, final DdiStatus ddiStatus) throws IOException { public void shouldSerializeAndDeserializeObject(final DdiResult ddiResult, final DdiStatus ddiStatus) throws IOException {
// Test // Test
String serializedDdiStatus = mapper.writeValueAsString(ddiStatus); final String serializedDdiStatus = OBJECT_MAPPER.writeValueAsString(ddiStatus);
DdiStatus deserializedDdiStatus = mapper.readValue(serializedDdiStatus, DdiStatus.class); final DdiStatus deserializedDdiStatus = OBJECT_MAPPER.readValue(serializedDdiStatus, DdiStatus.class);
assertThat(serializedDdiStatus).contains(ddiStatus.getExecution().getName(), ddiResult.getFinished().getName(), assertThat(serializedDdiStatus).contains(ddiStatus.getExecution().getName(), ddiResult.getFinished().getName(),
ddiResult.getProgress().getCnt().toString(), ddiResult.getProgress().getOf().toString()); ddiResult.getProgress().getCnt().toString(), ddiResult.getProgress().getOf().toString());
assertThat(deserializedDdiStatus.getExecution()).isEqualTo(ddiStatus.getExecution()); assertThat(deserializedDdiStatus.getExecution()).isEqualTo(ddiStatus.getExecution());
assertThat(deserializedDdiStatus.getResult().getFinished()).isEqualTo(ddiStatus.getResult().getFinished()); assertThat(deserializedDdiStatus.getResult().getFinished()).isEqualTo(ddiStatus.getResult().getFinished());
assertThat(deserializedDdiStatus.getResult().getProgress().getCnt()).isEqualTo( assertThat(deserializedDdiStatus.getResult().getProgress().getCnt()).isEqualTo(ddiStatus.getResult().getProgress().getCnt());
ddiStatus.getResult().getProgress().getCnt()); assertThat(deserializedDdiStatus.getResult().getProgress().getOf()).isEqualTo(ddiStatus.getResult().getProgress().getOf());
assertThat(deserializedDdiStatus.getResult().getProgress().getOf()).isEqualTo(
ddiStatus.getResult().getProgress().getOf());
assertThat(deserializedDdiStatus.getDetails()).isEqualTo(ddiStatus.getDetails()); assertThat(deserializedDdiStatus.getDetails()).isEqualTo(ddiStatus.getDetails());
} }
@@ -61,12 +58,11 @@ public class DdiStatusTest {
@Description("Verify the correct deserialization of a model with a additional unknown property") @Description("Verify the correct deserialization of a model with a additional unknown property")
public void shouldDeserializeObjectWithUnknownProperty() throws IOException { public void shouldDeserializeObjectWithUnknownProperty() throws IOException {
// Setup // Setup
final String serializedDdiStatus = "{\"execution\":\"proceeding\",\"result\":{\"finished\":\"none\"," final String serializedDdiStatus = "{\"execution\":\"proceeding\",\"result\":{\"finished\":\"none\"," +
+ "\"progress\":{\"cnt\":30,\"of\":100}},\"details\":[],\"unknownProperty\":\"test\"}"; "\"progress\":{\"cnt\":30,\"of\":100}},\"details\":[],\"unknownProperty\":\"test\"}";
// Test // Test
final DdiStatus ddiStatus = mapper.readValue(serializedDdiStatus, DdiStatus.class); final DdiStatus ddiStatus = OBJECT_MAPPER.readValue(serializedDdiStatus, DdiStatus.class);
assertThat(ddiStatus.getExecution()).isEqualTo(PROCEEDING); assertThat(ddiStatus.getExecution()).isEqualTo(PROCEEDING);
assertThat(ddiStatus.getCode()).isNull(); assertThat(ddiStatus.getCode()).isNull();
assertThat(ddiStatus.getResult().getFinished()).isEqualTo(NONE); assertThat(ddiStatus.getResult().getFinished()).isEqualTo(NONE);
@@ -78,12 +74,11 @@ public class DdiStatusTest {
@Description("Verify the correct deserialization of a model with a provided code (optional)") @Description("Verify the correct deserialization of a model with a provided code (optional)")
public void shouldDeserializeObjectWithOptionalCode() throws IOException { public void shouldDeserializeObjectWithOptionalCode() throws IOException {
// Setup // Setup
String serializedDdiStatus = "{\"execution\":\"proceeding\",\"result\":{\"finished\":\"none\"," final String serializedDdiStatus = "{\"execution\":\"proceeding\",\"result\":{\"finished\":\"none\"," +
+ "\"progress\":{\"cnt\":30,\"of\":100}},\"code\": 12,\"details\":[]}"; "\"progress\":{\"cnt\":30,\"of\":100}},\"code\": 12,\"details\":[]}";
// Test // Test
DdiStatus ddiStatus = mapper.readValue(serializedDdiStatus, DdiStatus.class); final DdiStatus ddiStatus = OBJECT_MAPPER.readValue(serializedDdiStatus, DdiStatus.class);
assertThat(ddiStatus.getExecution()).isEqualTo(PROCEEDING); assertThat(ddiStatus.getExecution()).isEqualTo(PROCEEDING);
assertThat(ddiStatus.getCode()).isEqualTo(12); assertThat(ddiStatus.getCode()).isEqualTo(12);
assertThat(ddiStatus.getResult().getFinished()).isEqualTo(NONE); assertThat(ddiStatus.getResult().getFinished()).isEqualTo(NONE);
@@ -95,12 +90,12 @@ public class DdiStatusTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype") @Description("Verify that deserialization fails for known properties with a wrong datatype")
public void shouldFailForObjectWithWrongDataTypes() throws IOException { public void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup // Setup
String serializedDdiStatus = "{\"execution\":[\"proceeding\"],\"result\":{\"finished\":\"none\"," final String serializedDdiStatus = "{\"execution\":[\"proceeding\"],\"result\":{\"finished\":\"none\"," +
+ "\"progress\":{\"cnt\":30,\"of\":100}},\"details\":[]}"; "\"progress\":{\"cnt\":30,\"of\":100}},\"details\":[]}";
// Test // Test
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy( assertThatExceptionOfType(MismatchedInputException.class)
() -> mapper.readValue(serializedDdiStatus, DdiStatus.class)); .isThrownBy(() -> OBJECT_MAPPER.readValue(serializedDdiStatus, DdiStatus.class));
} }
private static Stream<Arguments> ddiStatusPossibilities() { private static Stream<Arguments> ddiStatusPossibilities() {

View File

@@ -48,8 +48,7 @@ public class JsonIgnorePropertiesAnnotationTest {
} }
final JsonIgnoreProperties annotation = modelClass.getAnnotation(JsonIgnoreProperties.class); final JsonIgnoreProperties annotation = modelClass.getAnnotation(JsonIgnoreProperties.class);
assertThat(annotation) assertThat(annotation)
.describedAs( .describedAs("Annotation 'JsonIgnoreProperties' is missing for class: " + modelClass.getSimpleName())
"Annotation 'JsonIgnoreProperties' is missing for class: " + modelClass.getSimpleName())
.isNotNull(); .isNotNull();
assertThat(annotation.ignoreUnknown()).isTrue(); assertThat(annotation.ignoreUnknown()).isTrue();
}); });