@@ -47,9 +47,7 @@ public class DdiActionHistory {
|
||||
* @param messages is a list of messages retrieved from action history.
|
||||
*/
|
||||
@JsonCreator
|
||||
public DdiActionHistory(
|
||||
@JsonProperty("status") final String status,
|
||||
@JsonProperty("messages") final List<String> messages) {
|
||||
public DdiActionHistory(@JsonProperty("status") final String status, @JsonProperty("messages") final List<String> messages) {
|
||||
this.status = status;
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@@ -27,16 +28,10 @@ public class DdiActivateAutoConfirmation {
|
||||
"confirming future actions", example = "exampleRemark")
|
||||
private final String remark;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param initiator can be null
|
||||
* @param remark can be null
|
||||
*/
|
||||
@JsonCreator
|
||||
public DdiActivateAutoConfirmation(
|
||||
@JsonProperty(value = "initiator") final String initiator,
|
||||
@JsonProperty(value = "remark") final String remark) {
|
||||
@Nullable @JsonProperty(value = "initiator") final String initiator,
|
||||
@Nullable @JsonProperty(value = "remark") final String remark) {
|
||||
this.initiator = initiator;
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
* **download** - HTTPs Download resource for artifacts. The resource supports partial download as specified by RFC7233 (range requests). Keep in mind that the target needs to have the artifact assigned in order to be granted permission to download.
|
||||
* **md5sum** - HTTPs Download resource for MD5SUM file is an optional auto generated artifact that is especially useful for Linux based devices on order to check artifact consistency after download by using the md5sum command line tool. The MD5 and SHA1 are in addition available as metadata in the deployment command itself.
|
||||
* **download-http** - HTTP Download resource for artifacts. The resource supports partial download as specified by RFC7233 (range requests). Keep in mind that the target needs to have the artifact assigned in order to be granted permission to download. (note: anonymous download needs to be enabled on the service account for non-TLS access)
|
||||
* **md5sum-http** - HTTP Download resource for MD5SUM file is an optional auto generated artifact that is especially useful for Linux based devices on order to check artifact consistency after download by using the md5sum command line tool. The MD5 and SHA1 are in addition available as metadata in the deployment command itself. (note: anonymous download needs to be enabled on the service account for non-TLS access)
|
||||
* **md5sum-http** - HTTP Download resource for MD5SUM file is an optional auto generated artifact that is especially useful for Linux based devices on order to check artifact consistency after download by using the md5sum command line tool. The MD5 and SHA1 are in addition available as metadata in the deployment command itself. (note: anonymous download needs to be enabled on the service account for non-TLS access)
|
||||
""", example = """
|
||||
{
|
||||
"filename" : "binaryFile",
|
||||
@@ -47,10 +47,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/40/filename/binaryFile"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/40/filename/binaryFile"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/40/filename/binaryFile"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/40/filename/binaryFile.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/40/filename/binaryFile.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/40/filename/binaryFile.MD5SUM"
|
||||
|
||||
@@ -28,11 +28,6 @@ public class DdiConfig {
|
||||
|
||||
private final DdiPolling polling;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param polling configuration of the polling for the target
|
||||
*/
|
||||
@JsonCreator
|
||||
public DdiConfig(@JsonProperty("polling") final DdiPolling polling) {
|
||||
this.polling = polling;
|
||||
|
||||
@@ -57,8 +57,7 @@ public class DdiConfirmationBase extends RepresentationModel<DdiConfirmationBase
|
||||
private final DdiAutoConfirmationState autoConfirm;
|
||||
|
||||
@JsonCreator
|
||||
public DdiConfirmationBase(
|
||||
@JsonProperty(value = "autoConfirm", required = true) final DdiAutoConfirmationState autoConfirm) {
|
||||
public DdiConfirmationBase(@JsonProperty(value = "autoConfirm", required = true) final DdiAutoConfirmationState autoConfirm) {
|
||||
this.autoConfirm = autoConfirm;
|
||||
}
|
||||
}
|
||||
@@ -58,10 +58,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/binary.tgz"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/binary.tgz"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/binary.tgz"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/binary.tgz.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/binary.tgz.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/binary.tgz.MD5SUM"
|
||||
@@ -80,10 +80,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/file.signature"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/file.signature"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/file.signature"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/file.signature.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/file.signature.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/17/filename/file.signature.MD5SUM"
|
||||
@@ -107,10 +107,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/binary.tgz"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/binary.tgz"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/binary.tgz"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/binary.tgz.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/binary.tgz.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/binary.tgz.MD5SUM"
|
||||
@@ -129,10 +129,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/file.signature"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/file.signature"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/file.signature"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/file.signature.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/file.signature.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/16/filename/file.signature.MD5SUM"
|
||||
@@ -156,10 +156,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/binary.tgz"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/binary.tgz"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/binary.tgz"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/binary.tgz.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/binary.tgz.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/binary.tgz.MD5SUM"
|
||||
@@ -178,10 +178,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/file.signature"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/file.signature"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/file.signature"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/file.signature.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/file.signature.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/18/filename/file.signature.MD5SUM"
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
**_links**: Actions that the server has for the target
|
||||
* **deploymentBase** - Detailed deployment operation
|
||||
* **installedBase** - Detailed operation of last successfully finished action
|
||||
* **configData** - Link which is provided whenever the provisioning target or device is supposed to push its configuration data (aka. "controller attributes") to the server. Only shown for the initial configuration, after a successful update action, or if requested explicitly (e.g. via the management UI)
|
||||
* **configData** - Link which is provided whenever the provisioning target or device is supposed to push its configuration data (aka. "controller attributes") to the server. Only shown for the initial configuration, after a successful update action, or if requested explicitly (e.g. via the management UI)
|
||||
""",
|
||||
example = """
|
||||
{
|
||||
|
||||
@@ -100,7 +100,7 @@ public class DdiDeployment {
|
||||
*/
|
||||
FORCED("forced");
|
||||
|
||||
private String name;
|
||||
private final String name;
|
||||
|
||||
HandlingType(final String name) {
|
||||
this.name = name;
|
||||
@@ -128,7 +128,7 @@ public class DdiDeployment {
|
||||
*/
|
||||
UNAVAILABLE("unavailable");
|
||||
|
||||
private String status;
|
||||
private final String status;
|
||||
|
||||
DdiMaintenanceWindowStatus(final String status) {
|
||||
this.status = status;
|
||||
|
||||
@@ -54,10 +54,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/binary.tgz"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/binary.tgz"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/binary.tgz"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/binary.tgz.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/binary.tgz.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/binary.tgz.MD5SUM"
|
||||
@@ -76,10 +76,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/file.signature"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/file.signature"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/file.signature"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/file.signature.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/file.signature.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/23/filename/file.signature.MD5SUM"
|
||||
@@ -103,10 +103,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/binary.tgz"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/binary.tgz"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/binary.tgz"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/binary.tgz.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/binary.tgz.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/binary.tgz.MD5SUM"
|
||||
@@ -125,10 +125,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/file.signature"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/file.signature"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/file.signature"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/file.signature.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/file.signature.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/24/filename/file.signature.MD5SUM"
|
||||
@@ -152,10 +152,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/binary.tgz"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/binary.tgz"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/binary.tgz"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/binary.tgz.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/binary.tgz.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/binary.tgz.MD5SUM"
|
||||
@@ -174,10 +174,10 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/file.signature"
|
||||
},
|
||||
"download-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/file.signature"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/file.signature"
|
||||
},
|
||||
"md5sum-http" : {
|
||||
"href" : "http://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/file.signature.MD5SUM"
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/file.signature.MD5SUM"
|
||||
},
|
||||
"md5sum" : {
|
||||
"href" : "https://link-to-cdn.com/api/v1/TENANT_ID/download/controller/CONTROLLER_ID/softwaremodules/22/filename/file.signature.MD5SUM"
|
||||
|
||||
@@ -67,7 +67,7 @@ public class DdiResult {
|
||||
*/
|
||||
NONE("none");
|
||||
|
||||
private String name;
|
||||
private final String name;
|
||||
|
||||
FinalResult(final String name) {
|
||||
this.name = name;
|
||||
|
||||
@@ -13,8 +13,7 @@ package org.eclipse.hawkbit.ddi.json.model;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Enumerates the supported update modes. Each mode represents an attribute
|
||||
* update strategy.
|
||||
* Enumerates the supported update modes. Each mode represents an attribute update strategy.
|
||||
*
|
||||
* @see DdiConfigData
|
||||
*/
|
||||
|
||||
@@ -100,7 +100,7 @@ public interface DdiRootControllerRestApi {
|
||||
retrieve actions that need to be executed. Those are provided as a list of links to give more detailed
|
||||
information about the action. Links are only available for initial configuration, open actions, or the latest
|
||||
installed action, respectively. The resource supports Etag based modification checks in order to save traffic.
|
||||
|
||||
|
||||
Note: deployments have to be confirmed in order to move on to the next action. Cancellations have to be
|
||||
confirmed or rejected.""")
|
||||
@ApiResponses(value = {
|
||||
@@ -214,7 +214,7 @@ public interface DdiRootControllerRestApi {
|
||||
* the eTag needs to be re-generated
|
||||
* @param actionHistoryMessageCount specifies the number of messages to be returned from action history. Regardless of the passed value,
|
||||
* in order to restrict 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 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.
|
||||
@@ -222,7 +222,7 @@ public interface DdiRootControllerRestApi {
|
||||
*/
|
||||
@Operation(summary = "Resource for software module (Deployment Base)", description = """
|
||||
Core resource for deployment operations. Contains all information necessary in order to execute the operation.
|
||||
|
||||
|
||||
Keep in mind that the provided download links for the artifacts are generated dynamically by the update server.
|
||||
Host, port and path and not guaranteed to be similar to the provided examples below but will be defined at
|
||||
runtime.
|
||||
@@ -230,15 +230,14 @@ public interface DdiRootControllerRestApi {
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = """
|
||||
Successfully retrieved
|
||||
|
||||
|
||||
In case a device provides state information on the feedback channel and won’t store it locally,
|
||||
a query for, e.q, the last 10 messages, could be used which will include the previously provided by the
|
||||
device,
|
||||
feedback.
|
||||
|
||||
device, feedback.
|
||||
|
||||
In addition to the straight forward approach to inform the device to download and install the software
|
||||
in one transaction hawkBit supports the separation of download and installation into separate steps.
|
||||
|
||||
|
||||
This feature is called Maintenance Window where the device is informed to download the software first
|
||||
and then when it enters a defined (maintenance) window the installation triggers follows as usual.
|
||||
"""),
|
||||
@@ -373,7 +372,7 @@ public interface DdiRootControllerRestApi {
|
||||
*/
|
||||
@Operation(summary = "Cancel an action", description = """
|
||||
The Hawkbit server might cancel an operation, e.g. an unfinished update has a successor. It is up to the
|
||||
provisioning target to decide to accept the cancelation or reject it.""")
|
||||
provisioning target to decide to accept the cancellation or reject it.""")
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
|
||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||
@@ -450,7 +449,7 @@ public interface DdiRootControllerRestApi {
|
||||
* @param actionId of the {@link DdiDeploymentBase} that matches to installed action.
|
||||
* @param actionHistoryMessageCount specifies the number of messages to be returned from action
|
||||
* history. Regardless of the passed value, in order to restrict 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 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.
|
||||
@@ -461,7 +460,7 @@ public interface DdiRootControllerRestApi {
|
||||
the already finished action, for example in case a re-installation is necessary. The response will be of
|
||||
the same format as the deploymentBase operation, providing the previous action that has been finished
|
||||
successfully. As the action is already finished, no further feedback is expected.
|
||||
|
||||
|
||||
Keep in mind that the provided download links for the artifacts are generated dynamically by the update server.
|
||||
Host, port and path are not guaranteed to be similar to the provided examples below but will be defined at
|
||||
runtime.
|
||||
@@ -470,7 +469,7 @@ public interface DdiRootControllerRestApi {
|
||||
@ApiResponse(responseCode = "200", description = """
|
||||
The response body includes the detailed operation for the already finished action in the same format as
|
||||
for the deploymentBase operation.
|
||||
|
||||
|
||||
In this case the (optional) query for the last 10 messages, previously provided by the device, are included.
|
||||
"""),
|
||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||
@@ -546,7 +545,7 @@ public interface DdiRootControllerRestApi {
|
||||
* needs to be re-generated
|
||||
* @param actionHistoryMessageCount specifies the number of messages to be returned from action history. Regardless of the passed value,
|
||||
* in order to restrict resource utilization by controllers, maximum number of messages that are retrieved from database is limited
|
||||
* by {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}.
|
||||
* by 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.
|
||||
@@ -556,7 +555,7 @@ public interface DdiRootControllerRestApi {
|
||||
Resource to receive information about a pending confirmation. The response will be of the same format as the
|
||||
deploymentBase operation. The controller should provide feedback about the confirmation first, before
|
||||
processing the deployment.
|
||||
|
||||
|
||||
Keep in mind that the provided download links for the artifacts are generated dynamically by the update server.
|
||||
Host, port and path are not guaranteed to be similar to the provided examples below but will be defined at
|
||||
runtime.
|
||||
|
||||
@@ -49,7 +49,7 @@ class DdiActionHistoryTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -50,7 +50,7 @@ class DdiArtifactHashTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -53,7 +53,7 @@ class DdiArtifactTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -47,7 +47,7 @@ class DdiCancelActionToStopTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -48,7 +48,7 @@ class DdiCancelTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -54,7 +54,7 @@ class DdiChunkTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -46,7 +46,7 @@ class DdiConfigTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -64,7 +64,7 @@ class DdiConfirmationBaseTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -47,7 +47,7 @@ class DdiControllerBaseTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -58,7 +58,7 @@ class DdiDeploymentBaseTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -52,7 +52,7 @@ class DdiDeploymentTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -48,7 +48,7 @@ class DdiMetadataTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -45,7 +45,7 @@ class DdiPollingTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -46,7 +46,7 @@ class DdiProgressTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -49,7 +49,7 @@ class DdiResultTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -55,7 +55,7 @@ class DdiStatusTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the correct deserialization of a model with a additional unknown property
|
||||
* Verify the correct deserialization of a model with an additional unknown property
|
||||
*/
|
||||
@Test
|
||||
void shouldDeserializeObjectWithUnknownProperty() throws IOException {
|
||||
|
||||
@@ -14,10 +14,8 @@ import java.util.Map;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.eclipse.hawkbit.repository.artifact.urlhandler.ApiType;
|
||||
import org.eclipse.hawkbit.repository.artifact.urlhandler.ArtifactUrlHandler;
|
||||
import org.eclipse.hawkbit.repository.artifact.urlhandler.URLPlaceholder;
|
||||
import org.eclipse.hawkbit.repository.artifact.urlhandler.URLPlaceholder.SoftwareData;
|
||||
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver;
|
||||
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver.DownloadDescriptor;
|
||||
import org.eclipse.hawkbit.ddi.json.model.DdiArtifact;
|
||||
import org.eclipse.hawkbit.ddi.json.model.DdiArtifactHash;
|
||||
import org.eclipse.hawkbit.ddi.json.model.DdiAutoConfirmationState;
|
||||
@@ -121,6 +119,7 @@ public final class DataConversionHelper {
|
||||
result.add(WebMvcLinkBuilder
|
||||
.linkTo(WebMvcLinkBuilder
|
||||
.methodOn(DdiRootController.class, tenantAware.getCurrentTenant())
|
||||
// doesn't really call the putConfigData with null, just create the link
|
||||
.putConfigData(null, tenantAware.getCurrentTenant(), target.getControllerId()))
|
||||
.withRel(DdiRestConstants.CONFIG_DATA_ACTION).expand());
|
||||
}
|
||||
@@ -130,7 +129,7 @@ public final class DataConversionHelper {
|
||||
|
||||
static List<DdiChunk> createChunks(
|
||||
final Target target, final Action uAction,
|
||||
final ArtifactUrlHandler artifactUrlHandler, final SystemManagement systemManagement,
|
||||
final ArtifactUrlResolver artifactUrlHandler, final SystemManagement systemManagement,
|
||||
final HttpRequest request, final ControllerManagement controllerManagement) {
|
||||
final Map<Long, Map<String, String>> metadata = controllerManagement
|
||||
.findTargetVisibleMetaDataBySoftwareModuleId(uAction.getDistributionSet().getModules().stream()
|
||||
@@ -146,7 +145,7 @@ public final class DataConversionHelper {
|
||||
}
|
||||
|
||||
static List<DdiArtifact> createArtifacts(final Target target, final SoftwareModule module,
|
||||
final ArtifactUrlHandler artifactUrlHandler, final SystemManagement systemManagement,
|
||||
final ArtifactUrlResolver artifactUrlHandler, final SystemManagement systemManagement,
|
||||
final HttpRequest request) {
|
||||
|
||||
return new ResponseList<>(module.getArtifacts().stream()
|
||||
@@ -171,7 +170,7 @@ public final class DataConversionHelper {
|
||||
}
|
||||
|
||||
private static DdiArtifact createArtifact(
|
||||
final Target target, final ArtifactUrlHandler artifactUrlHandler,
|
||||
final Target target, final ArtifactUrlResolver artifactUrlHandler,
|
||||
final Artifact artifact, final SystemManagement systemManagement, final HttpRequest request) {
|
||||
final DdiArtifact file = new DdiArtifact(
|
||||
artifact.getFilename(),
|
||||
@@ -180,13 +179,11 @@ public final class DataConversionHelper {
|
||||
|
||||
final TenantMetaData tenantMetadata = systemManagement.getTenantMetadataWithoutDetails();
|
||||
artifactUrlHandler
|
||||
.getUrls(new URLPlaceholder(
|
||||
tenantMetadata.getTenant(), tenantMetadata.getId(), target.getControllerId(), target.getId(),
|
||||
new SoftwareData(
|
||||
artifact.getSoftwareModule().getId(), artifact.getFilename(), artifact.getId(),
|
||||
artifact.getSha1Hash())),
|
||||
ApiType.DDI, request.getURI())
|
||||
.forEach(entry -> file.add(Link.of(entry.getRef()).withRel(entry.getRel()).expand()));
|
||||
.getUrls(new DownloadDescriptor(
|
||||
tenantMetadata.getTenant(), target.getControllerId(),
|
||||
artifact.getSoftwareModule().getId(), artifact.getFilename(), artifact.getSha1Hash()),
|
||||
ArtifactUrlResolver.ApiType.DDI, request.getURI())
|
||||
.forEach(entry -> file.add(Link.of(entry.ref()).withRel(entry.rel()).expand()));
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
@@ -17,11 +17,10 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
/**
|
||||
* Enable {@link ComponentScan} in the resource package to setup all
|
||||
* {@link Controller} annotated classes and setup the REST-Resources for the
|
||||
* Enable {@link ComponentScan} in the resource package to set up all {@link Controller} annotated classes and set up the REST-Resources for the
|
||||
* Direct Device Integration API.
|
||||
*/
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
@Import({ RestConfiguration.class, OpenApi.class, DdiOpenApiConfiguration.class })
|
||||
public class DdiApiConfiguration {}
|
||||
public class DdiApiConfiguration {}
|
||||
@@ -21,6 +21,8 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.hawkbit.artifact.model.ArtifactStream;
|
||||
import org.eclipse.hawkbit.artifact.urlresolver.ArtifactUrlResolver;
|
||||
import org.eclipse.hawkbit.audit.AuditLog;
|
||||
import org.eclipse.hawkbit.ddi.json.model.DdiActionFeedback;
|
||||
import org.eclipse.hawkbit.ddi.json.model.DdiActionHistory;
|
||||
@@ -50,13 +52,10 @@ import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||
import org.eclipse.hawkbit.repository.UpdateMode;
|
||||
import org.eclipse.hawkbit.repository.artifact.model.DbArtifact;
|
||||
import org.eclipse.hawkbit.repository.artifact.urlhandler.ArtifactUrlHandler;
|
||||
import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidConfirmationFeedbackException;
|
||||
import org.eclipse.hawkbit.repository.exception.SoftwareModuleNotAssignedToTargetException;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionStatusCreate;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionStatusCreate.ActionStatusCreateBuilder;
|
||||
@@ -99,7 +98,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
private final ControllerManagement controllerManagement;
|
||||
private final ConfirmationManagement confirmationManagement;
|
||||
private final ArtifactManagement artifactManagement;
|
||||
private final ArtifactUrlHandler artifactUrlHandler;
|
||||
private final ArtifactUrlResolver artifactUrlHandler;
|
||||
private final SystemManagement systemManagement;
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
private final HawkbitSecurityProperties securityProperties;
|
||||
@@ -108,7 +107,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
@SuppressWarnings("java:S107")
|
||||
public DdiRootController(
|
||||
final ControllerManagement controllerManagement, final ConfirmationManagement confirmationManagement,
|
||||
final ArtifactManagement artifactManagement, final ArtifactUrlHandler artifactUrlHandler,
|
||||
final ArtifactManagement artifactManagement, final ArtifactUrlResolver artifactUrlHandler,
|
||||
final SystemManagement systemManagement,
|
||||
final ApplicationEventPublisher eventPublisher,
|
||||
final HawkbitSecurityProperties securityProperties, final TenantAware tenantAware) {
|
||||
@@ -131,11 +130,10 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
|
||||
final Target target = findTarget(controllerId);
|
||||
|
||||
final SoftwareModule softwareModule = controllerManagement.getSoftwareModule(softwareModuleId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
||||
|
||||
final SoftwareModule softwareModule = controllerManagement.getSoftwareModule(softwareModuleId);
|
||||
return new ResponseEntity<>(
|
||||
DataConversionHelper.createArtifacts(target, softwareModule, artifactUrlHandler, systemManagement,
|
||||
DataConversionHelper.createArtifacts(
|
||||
target, softwareModule, artifactUrlHandler, systemManagement,
|
||||
new ServletServerHttpRequest(RequestResponseContextHolder.getHttpServletRequest())),
|
||||
HttpStatus.OK);
|
||||
}
|
||||
@@ -147,7 +145,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(
|
||||
controllerId, IpUtil.getClientIpFromRequest(RequestResponseContextHolder.getHttpServletRequest(), securityProperties));
|
||||
final Action activeAction = controllerManagement.findActiveActionWithHighestWeight(controllerId).orElse(null);
|
||||
final Action installedAction = controllerManagement.getInstalledActionByTarget(target).orElse(null);
|
||||
final Action installedAction = controllerManagement.findInstalledActionByTarget(target).orElse(null);
|
||||
|
||||
checkAndCancelExpiredAction(activeAction);
|
||||
|
||||
@@ -170,16 +168,14 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
final ResponseEntity<InputStream> result;
|
||||
|
||||
final Target target = findTarget(controllerId);
|
||||
final SoftwareModule module = controllerManagement.getSoftwareModule(softwareModuleId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
||||
|
||||
final SoftwareModule module = controllerManagement.getSoftwareModule(softwareModuleId);
|
||||
if (checkModule(fileName, module)) {
|
||||
log.warn("Software module with id {} could not be found (1).", softwareModuleId);
|
||||
result = ResponseEntity.notFound().build();
|
||||
} else {
|
||||
// Artifact presence is ensured in 'checkModule'
|
||||
final Artifact artifact = module.getArtifactByFilename(fileName).orElseThrow(NoSuchElementException::new);
|
||||
final DbArtifact file = artifactManagement.loadArtifactBinary(artifact.getSha1Hash(), module.getId(), module.isEncrypted());
|
||||
final ArtifactStream file = artifactManagement.getArtifactStream(artifact.getSha1Hash(), module.getId(), module.isEncrypted());
|
||||
|
||||
final String ifMatch = RequestResponseContextHolder.getHttpServletRequest().getHeader(HttpHeaders.IF_MATCH);
|
||||
if (ifMatch != null && !HttpUtil.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) {
|
||||
@@ -212,9 +208,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
final String fileName) {
|
||||
final Target target = findTarget(controllerId);
|
||||
|
||||
final SoftwareModule module = controllerManagement.getSoftwareModule(softwareModuleId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId));
|
||||
|
||||
final SoftwareModule module = controllerManagement.getSoftwareModule(softwareModuleId);
|
||||
if (checkModule(fileName, module)) {
|
||||
log.warn("Software module with id {} could not be found (2).", softwareModuleId);
|
||||
return ResponseEntity.notFound().build();
|
||||
@@ -596,9 +590,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
}
|
||||
|
||||
private ActionStatus logDownload(final HttpServletRequest request, final Target target, final Long module) {
|
||||
final Action action = controllerManagement
|
||||
.getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), module)
|
||||
.orElseThrow(() -> new SoftwareModuleNotAssignedToTargetException(module, target.getControllerId()));
|
||||
final Action action = controllerManagement.getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), module);
|
||||
return controllerManagement.addInformationalActionStatus(
|
||||
ActionStatusCreate.builder()
|
||||
.actionId(action.getId())
|
||||
@@ -750,16 +742,16 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
}
|
||||
|
||||
private Optional<DdiActionHistory> generateDdiActionHistory(final Action action, final Integer actionHistoryMessageCount) {
|
||||
final List<String> actionHistoryMsgs = controllerManagement.getActionHistoryMessages(
|
||||
final List<String> actionHistoryMessages = controllerManagement.getActionHistoryMessages(
|
||||
action.getId(),
|
||||
actionHistoryMessageCount == null ? Integer.parseInt(DdiRestConstants.NO_ACTION_HISTORY) : actionHistoryMessageCount);
|
||||
return actionHistoryMsgs.isEmpty()
|
||||
return actionHistoryMessages.isEmpty()
|
||||
? Optional.empty()
|
||||
: Optional.of(new DdiActionHistory(action.getStatus().name(), actionHistoryMsgs));
|
||||
: Optional.of(new DdiActionHistory(action.getStatus().name(), actionHistoryMessages));
|
||||
}
|
||||
|
||||
private DdiAutoConfirmationState getAutoConfirmationState(final String controllerId) {
|
||||
return confirmationManagement.getStatus(controllerId).map(status -> {
|
||||
return confirmationManagement.findStatus(controllerId).map(status -> {
|
||||
final DdiAutoConfirmationState state = new DdiAutoConfirmationState(
|
||||
true, status.getInitiator(), status.getRemark(), status.getActivatedAt());
|
||||
log.trace("Returning state auto-conf state active [initiator='{}' | activatedAt={}] for device {}",
|
||||
|
||||
@@ -39,12 +39,8 @@ import org.eclipse.hawkbit.ddi.json.model.DdiConfirmationFeedback;
|
||||
import org.eclipse.hawkbit.ddi.json.model.DdiProgress;
|
||||
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
|
||||
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
|
||||
import org.eclipse.hawkbit.repository.jpa.JpaRepositoryConfiguration;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
@@ -171,7 +167,7 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
||||
|
||||
protected ResultActions performGet(final String url, final MediaType mediaType, final ResultMatcher statusMatcher, final String... values)
|
||||
throws Exception {
|
||||
return mvc.perform(MockMvcRequestBuilders.get(url, values).accept(mediaType)
|
||||
return mvc.perform(MockMvcRequestBuilders.get(url, (Object[]) values).accept(mediaType)
|
||||
.with(new RequestOnHawkbitDefaultPortPostProcessor()))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(statusMatcher)
|
||||
@@ -281,14 +277,12 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
||||
}
|
||||
|
||||
protected String getJsonClosedDeploymentActionFeedback() throws JsonProcessingException {
|
||||
return getJsonActionFeedback(
|
||||
DdiStatus.ExecutionStatus.CLOSED, DdiResult.FinalResult.NONE, Collections.singletonList("closed"));
|
||||
return getJsonActionFeedback(DdiStatus.ExecutionStatus.CLOSED, DdiResult.FinalResult.NONE, Collections.singletonList("closed"));
|
||||
}
|
||||
|
||||
protected String getJsonActionFeedback(
|
||||
final DdiStatus.ExecutionStatus executionStatus, final DdiResult.FinalResult finalResult) throws JsonProcessingException {
|
||||
return getJsonActionFeedback(
|
||||
executionStatus, finalResult, Collections.singletonList(randomString(1000)));
|
||||
return getJsonActionFeedback(executionStatus, finalResult, Collections.singletonList(randomString(1000)));
|
||||
}
|
||||
|
||||
protected String getJsonActionFeedback(
|
||||
@@ -376,10 +370,10 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
||||
contains(artifact.getSha256Hash())))
|
||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[0]._links.download-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId +
|
||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifact.getFilename() + "/download")))
|
||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifact.getFilename())))
|
||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[0]._links.md5sum-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId +
|
||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifact.getFilename() + "/download.MD5SUM")))
|
||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifact.getFilename() + ".MD5SUM")))
|
||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1].size", contains(ARTIFACT_SIZE)))
|
||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1].filename",
|
||||
contains(artifactSignature.getFilename())))
|
||||
@@ -391,10 +385,10 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat
|
||||
contains(artifactSignature.getSha256Hash())))
|
||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1]._links.download-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId +
|
||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifactSignature.getFilename() + "/download")))
|
||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifactSignature.getFilename())))
|
||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='os')].artifacts[1]._links.md5sum-http.href",
|
||||
contains(HTTP_LOCALHOST + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId +
|
||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifactSignature.getFilename() + "/download.MD5SUM")))
|
||||
"/softwaremodules/" + osModuleId + "/artifacts/" + artifactSignature.getFilename() + ".MD5SUM")))
|
||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='bApp')].version",
|
||||
contains(findFirstModuleByType(ds, appType).orElseThrow().getVersion())))
|
||||
.andExpect(jsonPath(prefix + ".chunks[?(@.part=='bApp')].metadata").doesNotExist())
|
||||
|
||||
@@ -57,8 +57,8 @@ import org.springframework.test.web.servlet.MvcResult;
|
||||
@SpringBootTest(classes = { DownloadTestConfiguration.class })
|
||||
class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
private static volatile int downloadProgress = 0;
|
||||
private static volatile long shippedBytes = 0;
|
||||
private static int downloadProgress = 0;
|
||||
private static long shippedBytes = 0;
|
||||
|
||||
private final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
|
||||
|
||||
@@ -68,7 +68,7 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests non allowed requests on the artifact ressource, e.g. invalid URI, wrong if-match, wrong command.
|
||||
* Tests not allowed requests on the artifact resource, e.g. invalid URI, wrong if-match, wrong command.
|
||||
*/
|
||||
@Test
|
||||
void invalidRequestsOnArtifactResource() throws Exception {
|
||||
@@ -83,7 +83,8 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
||||
final int artifactSize = 5 * 1024;
|
||||
final byte[] random = nextBytes(artifactSize);
|
||||
final Artifact artifact = artifactManagement.create(new ArtifactUpload(
|
||||
new ByteArrayInputStream(random), findFirstModuleByType(ds, osType).orElseThrow().getId(), "file1", false, artifactSize));
|
||||
new ByteArrayInputStream(random), null, artifactSize, null,
|
||||
findFirstModuleByType(ds, osType).orElseThrow().getId(), "file1", false));
|
||||
|
||||
assignDistributionSet(ds, targets);
|
||||
|
||||
@@ -163,8 +164,10 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
||||
@Test
|
||||
@WithUser(principal = "4712", authorities = "ROLE_CONTROLLER", allSpPermissions = true)
|
||||
void downloadArtifactThroughFileName() throws Exception {
|
||||
downloadProgress = 1;
|
||||
shippedBytes = 0;
|
||||
synchronized (DdiArtifactDownloadTest.class) {
|
||||
downloadProgress = 1;
|
||||
shippedBytes = 0;
|
||||
}
|
||||
assertThat(softwareModuleManagement.findAll(PAGE)).isEmpty();
|
||||
|
||||
// create target
|
||||
@@ -177,8 +180,9 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
||||
// create artifact
|
||||
final int artifactSize = (int) quotaManagement.getMaxArtifactSize();
|
||||
final byte[] random = nextBytes(artifactSize);
|
||||
final Artifact artifact = artifactManagement.create(new ArtifactUpload(new ByteArrayInputStream(random),
|
||||
findFirstModuleByType(ds, osType).orElseThrow().getId(), "file1", false, artifactSize));
|
||||
final Artifact artifact = artifactManagement.create(new ArtifactUpload(
|
||||
new ByteArrayInputStream(random), null, artifactSize, null,
|
||||
findFirstModuleByType(ds, osType).orElseThrow().getId(), "file1", false));
|
||||
|
||||
// download fails as artifact is not yet assigned
|
||||
mvc.perform(get("/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{filename}",
|
||||
@@ -197,12 +201,13 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
||||
.andExpect(header().string("Content-Disposition", "attachment;filename=" + artifact.getFilename()))
|
||||
.andReturn();
|
||||
|
||||
assertArrayEquals(result.getResponse().getContentAsByteArray(), random,
|
||||
"The same file that was uploaded is expected when downloaded");
|
||||
assertArrayEquals(result.getResponse().getContentAsByteArray(), random, "The same file that was uploaded is expected when downloaded");
|
||||
|
||||
// download complete
|
||||
assertThat(downloadProgress).isEqualTo(10);
|
||||
assertThat(shippedBytes).isEqualTo(artifactSize);
|
||||
synchronized (DdiArtifactDownloadTest.class) {
|
||||
assertThat(downloadProgress).isEqualTo(10);
|
||||
assertThat(shippedBytes).isEqualTo(artifactSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,8 +224,9 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
||||
// create artifact
|
||||
final int artifactSize = 5 * 1024;
|
||||
final byte[] random = nextBytes(artifactSize);
|
||||
final Artifact artifact = artifactManagement.create(
|
||||
new ArtifactUpload(new ByteArrayInputStream(random), getOsModule(ds), "file1", false, artifactSize));
|
||||
final Artifact artifact = artifactManagement.create(new ArtifactUpload(
|
||||
new ByteArrayInputStream(random), null, artifactSize, null,
|
||||
getOsModule(ds), "file1", false));
|
||||
|
||||
assignDistributionSet(ds, target);
|
||||
|
||||
@@ -254,8 +260,9 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
// create artifact
|
||||
final byte[] random = nextBytes(resultLength);
|
||||
final Artifact artifact = artifactManagement.create(
|
||||
new ArtifactUpload(new ByteArrayInputStream(random), getOsModule(ds), "file1", false, resultLength));
|
||||
final Artifact artifact = artifactManagement.create(new ArtifactUpload(
|
||||
new ByteArrayInputStream(random), null, resultLength, null,
|
||||
getOsModule(ds), "file1", false));
|
||||
|
||||
assertThat(random).hasSize(resultLength);
|
||||
|
||||
@@ -379,8 +386,10 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@EventListener(classes = DownloadProgressEvent.class)
|
||||
void listen(final DownloadProgressEvent event) {
|
||||
downloadProgress++;
|
||||
shippedBytes += event.getShippedBytesSinceLast();
|
||||
synchronized (DdiArtifactDownloadTest.class) {
|
||||
downloadProgress++;
|
||||
shippedBytes += event.getShippedBytesSinceLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,18 +139,18 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
.andExpect(status().isOk());
|
||||
|
||||
// check database after test
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(TestdataFactory.DEFAULT_CONTROLLER_ID).get())
|
||||
assertThat(deploymentManagement.findAssignedDistributionSet(TestdataFactory.DEFAULT_CONTROLLER_ID).orElseThrow())
|
||||
.isEqualTo(ds);
|
||||
assertThat(deploymentManagement.getInstalledDistributionSet(TestdataFactory.DEFAULT_CONTROLLER_ID).get())
|
||||
assertThat(deploymentManagement.findInstalledDistributionSet(TestdataFactory.DEFAULT_CONTROLLER_ID).orElseThrow())
|
||||
.isEqualTo(ds);
|
||||
assertThat(
|
||||
targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getInstallationDate())
|
||||
targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).getInstallationDate())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for cancel operation of a update action.
|
||||
* Test for cancel operation of an update action.
|
||||
*/
|
||||
@Test
|
||||
void rootRsCancelAction() throws Exception {
|
||||
@@ -171,7 +171,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
startsWith("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId)));
|
||||
final long timeAfterFirstPoll = System.currentTimeMillis() + 1;
|
||||
assertThat(targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
assertThat(targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).getLastTargetQuery())
|
||||
.isBetween(timeBeforeFirstPoll, timeAfterFirstPoll);
|
||||
|
||||
// Retrieved is reported
|
||||
@@ -202,7 +202,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/"
|
||||
+ TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction.getId())));
|
||||
final long timeAfter2ndPoll = System.currentTimeMillis() + 1;
|
||||
assertThat(targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
assertThat(targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).getLastTargetQuery())
|
||||
.isBetween(timeBefore2ndPoll, timeAfter2ndPoll);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||
@@ -212,7 +212,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(jsonPath("$.id", equalTo(String.valueOf(cancelAction.getId()))))
|
||||
.andExpect(jsonPath("$.cancelAction.stopId", equalTo(String.valueOf(actionId))));
|
||||
assertThat(targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
assertThat(targetManagement.getByControllerId(TestdataFactory.DEFAULT_CONTROLLER_ID).getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
|
||||
// controller confirmed cancelled action, should not be active anymore
|
||||
@@ -226,7 +226,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
activeActionsByTarget = deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)
|
||||
.getContent();
|
||||
assertThat(activeActionsByTarget).isEmpty();
|
||||
final Action canceledAction = deploymentManagement.findAction(cancelAction.getId()).get();
|
||||
final Action canceledAction = deploymentManagement.findAction(cancelAction.getId()).orElseThrow();
|
||||
assertThat(canceledAction.isActive()).isFalse();
|
||||
assertThat(canceledAction.getStatus()).isEqualTo(Status.CANCELED);
|
||||
|
||||
@@ -355,6 +355,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
/**
|
||||
* Tests the feeback chanel of for multiple open cancel operations on the same target.
|
||||
*/
|
||||
@SuppressWarnings("java:S5961")
|
||||
@Test
|
||||
void multipleCancelActionFeedback() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
|
||||
@@ -363,14 +364,11 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
final Target savedTarget = testdataFactory.createTarget();
|
||||
|
||||
final Long actionId = getFirstAssignedActionId(
|
||||
assignDistributionSet(ds.getId(), TestdataFactory.DEFAULT_CONTROLLER_ID));
|
||||
final Long actionId = getFirstAssignedActionId(assignDistributionSet(ds.getId(), TestdataFactory.DEFAULT_CONTROLLER_ID));
|
||||
implicitLock(ds);
|
||||
final Long actionId2 = getFirstAssignedActionId(
|
||||
assignDistributionSet(ds2.getId(), TestdataFactory.DEFAULT_CONTROLLER_ID));
|
||||
final Long actionId2 = getFirstAssignedActionId(assignDistributionSet(ds2.getId(), TestdataFactory.DEFAULT_CONTROLLER_ID));
|
||||
implicitLock(ds2);
|
||||
final Long actionId3 = getFirstAssignedActionId(
|
||||
assignDistributionSet(ds3.getId(), TestdataFactory.DEFAULT_CONTROLLER_ID));
|
||||
final Long actionId3 = getFirstAssignedActionId(assignDistributionSet(ds3.getId(), TestdataFactory.DEFAULT_CONTROLLER_ID));
|
||||
implicitLock(ds3);
|
||||
|
||||
assertThat(countActionStatusAll()).isEqualTo(3);
|
||||
@@ -383,8 +381,9 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).hasSize(3);
|
||||
assertThat(deploymentManagement.countActionsByTarget(savedTarget.getControllerId())).isEqualTo(3);
|
||||
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||
+ cancelAction.getId(), tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
||||
mvc.perform(get(
|
||||
"/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction.getId(),
|
||||
tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||
@@ -442,8 +441,7 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
.andExpect(status().isOk());
|
||||
assertThat(countActionStatusAll()).isEqualTo(9);
|
||||
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(TestdataFactory.DEFAULT_CONTROLLER_ID).get())
|
||||
.isEqualTo(ds3);
|
||||
assertThat(deploymentManagement.findAssignedDistributionSet(TestdataFactory.DEFAULT_CONTROLLER_ID).orElseThrow()).isEqualTo(ds3);
|
||||
mvc.perform(
|
||||
get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/deploymentBase/" + actionId3,
|
||||
tenantAware.getCurrentTenant()))
|
||||
@@ -459,11 +457,11 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
|
||||
// action is in cancelling state
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).hasSize(1);
|
||||
assertThat(deploymentManagement.countActionsByTarget(savedTarget.getControllerId())).isEqualTo(3);
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(TestdataFactory.DEFAULT_CONTROLLER_ID).get())
|
||||
.isEqualTo(ds3);
|
||||
assertThat(deploymentManagement.findAssignedDistributionSet(TestdataFactory.DEFAULT_CONTROLLER_ID).orElseThrow()).isEqualTo(ds3);
|
||||
|
||||
mvc.perform(get("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/"
|
||||
+ cancelAction3.getId(), tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
||||
mvc.perform(get(
|
||||
"/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/" + cancelAction3.getId(),
|
||||
tenantAware.getCurrentTenant()).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
|
||||
@@ -72,11 +72,11 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
/**
|
||||
* We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) are requested only once from the device.")
|
||||
*/
|
||||
@SuppressWarnings("squid:S2925")
|
||||
@Test
|
||||
void requestConfigDataIfEmpty() throws Exception {
|
||||
final Target savedTarget = testdataFactory.createTarget("4712");
|
||||
|
||||
@@ -90,10 +90,10 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
||||
"http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/4712/configData")));
|
||||
Thread.sleep(1); // is required: otherwise processing the next line is
|
||||
// often too fast and // the following assert will fail
|
||||
assertThat(targetManagement.getByControllerId("4712").orElseThrow(NoSuchElementException::new)
|
||||
assertThat(targetManagement.getByControllerId("4712")
|
||||
.getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(targetManagement.getByControllerId("4712").orElseThrow(NoSuchElementException::new)
|
||||
assertThat(targetManagement.getByControllerId("4712")
|
||||
.getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
|
||||
@@ -140,7 +140,7 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
/**
|
||||
* We verify that the config data (i.e. device attributes like serial number, hardware revision etc.)
|
||||
* upload quota is enforced to protect the server from malicious attempts.""")
|
||||
* upload quota is enforced to protect the server from malicious attempts.
|
||||
*/
|
||||
@Test
|
||||
void putTooMuchConfigData() throws Exception {
|
||||
|
||||
@@ -113,13 +113,12 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.andExpect(jsonPath("$._links.confirmationBase.href", containsString(expectedConfirmationBaseLink)))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href").doesNotExist());
|
||||
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(actionStatusRepository.count()).isEqualTo(2);
|
||||
|
||||
final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).get();
|
||||
final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).orElseThrow();
|
||||
|
||||
getAndVerifyConfirmationBasePayload(
|
||||
DEFAULT_CONTROLLER_ID, MediaType.APPLICATION_JSON, ds, artifact,
|
||||
@@ -142,7 +141,7 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
final Target target = testdataFactory.createTarget();
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("");
|
||||
|
||||
final Long softwareModuleId = distributionSet.getModules().stream().findAny().get().getId();
|
||||
final Long softwareModuleId = distributionSet.getModules().stream().findAny().orElseThrow().getId();
|
||||
testdataFactory.createArtifacts(softwareModuleId);
|
||||
|
||||
assignDistributionSet(distributionSet.getId(), target.getName());
|
||||
@@ -359,7 +358,7 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
assertThat(confirmationManagement.getStatus(controllerId)).hasValueSatisfying(status -> {
|
||||
assertThat(confirmationManagement.findStatus(controllerId)).hasValueSatisfying(status -> {
|
||||
assertThat(status.getInitiator()).isEqualTo(initiator);
|
||||
assertThat(status.getRemark()).isEqualTo(remark);
|
||||
assertThat(status.getCreatedBy()).isEqualTo("bumlux");
|
||||
@@ -379,7 +378,7 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
assertThat(confirmationManagement.getStatus(controllerId)).isEmpty();
|
||||
assertThat(confirmationManagement.findStatus(controllerId)).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,7 +41,6 @@ import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionStatusRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.ActionSpecifications;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
@@ -89,7 +88,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
final Target target = testdataFactory.createTarget();
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("");
|
||||
|
||||
final Long softwareModuleId = distributionSet.getModules().stream().findAny().get().getId();
|
||||
final Long softwareModuleId = distributionSet.getModules().stream().findAny().orElseThrow().getId();
|
||||
testdataFactory.createArtifacts(softwareModuleId);
|
||||
|
||||
assignDistributionSet(distributionSet.getId(), target.getName());
|
||||
@@ -128,7 +127,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
final Target target = testdataFactory.createTarget();
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("");
|
||||
|
||||
final Long softwareModuleId = distributionSet.getModules().stream().findAny().get().getId();
|
||||
final Long softwareModuleId = distributionSet.getModules().stream().findAny().orElseThrow().getId();
|
||||
testdataFactory.createArtifacts(softwareModuleId);
|
||||
|
||||
assignDistributionSet(distributionSet.getId(), target.getName());
|
||||
@@ -181,10 +180,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.andExpect(jsonPath(
|
||||
"$._links.deploymentBase.href",
|
||||
startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, uaction.getId().toString()))));
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertLastTargetQueryUpdated(current);
|
||||
assertThat(countActionStatusAll()).isEqualTo(2);
|
||||
|
||||
final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).get();
|
||||
@@ -281,10 +277,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, uaction.getId().toString()))));
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertLastTargetQueryUpdated(current);
|
||||
assertThat(countActionStatusAll()).isEqualTo(2);
|
||||
|
||||
final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).get();
|
||||
@@ -338,10 +331,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, uaction.getId().toString()))));
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertLastTargetQueryUpdated(current);
|
||||
assertThat(countActionStatusAll()).isEqualTo(2);
|
||||
|
||||
final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).get();
|
||||
@@ -398,15 +388,11 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
// Run test
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(),
|
||||
DEFAULT_CONTROLLER_ID)
|
||||
performGet(CONTROLLER_BASE, MediaTypes.HAL_JSON, status().isOk(), tenantAware.getCurrentTenant(), DEFAULT_CONTROLLER_ID)
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")))
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href",
|
||||
startsWith(deploymentBaseLink(DEFAULT_CONTROLLER_ID, uaction.getId().toString()))));
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertLastTargetQueryUpdated(current);
|
||||
assertThat(countActionStatusAll()).isEqualTo(2);
|
||||
|
||||
final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).get();
|
||||
@@ -490,7 +476,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* The server protects itself against too large feedback bodies. The test verifies that
|
||||
* The server protects itself against too large feedback bodies. The test verifies that
|
||||
* it is not possible to exceed the configured maximum number of feedback details.
|
||||
*/
|
||||
@Test
|
||||
@@ -560,7 +546,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
final Target savedTarget = testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
|
||||
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get().getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
assignDistributionSet(ds, Collections.singletonList(savedTarget));
|
||||
final Action action = actionRepository
|
||||
.findAll(byDistributionSetId(ds.getId()), PAGE)
|
||||
@@ -576,8 +562,8 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
assertTargetCountByStatus(0, 1, 0);
|
||||
|
||||
// redo
|
||||
ds = distributionSetManagement.getWithDetails(ds.getId()).get();
|
||||
assignDistributionSet(ds, Collections.singletonList(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID).get()));
|
||||
ds = distributionSetManagement.getWithDetails(ds.getId());
|
||||
assignDistributionSet(ds, Collections.singletonList(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID)));
|
||||
final Action action2 = deploymentManagement.findActiveActionsByTarget(DEFAULT_CONTROLLER_ID, PAGE).getContent().get(0);
|
||||
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, action2.getId(), getJsonClosedCancelActionFeedback(), status().isOk());
|
||||
findTargetAndAssertUpdateStatus(Optional.of(ds), TargetUpdateStatus.IN_SYNC, 0, Optional.of(ds));
|
||||
@@ -741,9 +727,8 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
assignDistributionSet(ds.getId(), "1080");
|
||||
|
||||
final Action action = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent().get(0);
|
||||
final String missingFinishedResultInFeedback = getJsonActionFeedback(DdiStatus.ExecutionStatus.CLOSED,
|
||||
new DdiResult(null, null),
|
||||
Collections.singletonList("test"));
|
||||
final String missingFinishedResultInFeedback = getJsonActionFeedback(
|
||||
DdiStatus.ExecutionStatus.CLOSED, new DdiResult(null, null), Collections.singletonList("test"));
|
||||
|
||||
postDeploymentFeedback("1080", action.getId(), missingFinishedResultInFeedback, status().isBadRequest())
|
||||
.andExpect(jsonPath("$.*", hasSize(3)))
|
||||
@@ -766,15 +751,14 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
}
|
||||
|
||||
private void assertActionStatusCount(final int actionStatusCount, final int minActionStatusCountInPage) {
|
||||
final Target target = targetManagement.getByControllerId(DdiDeploymentBaseTest.DEFAULT_CONTROLLER_ID).get();
|
||||
final Target target = targetManagement.getByControllerId(DdiDeploymentBaseTest.DEFAULT_CONTROLLER_ID);
|
||||
assertThat(target.getUpdateStatus()).isEqualTo(TargetUpdateStatus.PENDING);
|
||||
|
||||
assertTargetCountByStatus(1, 0, 0);
|
||||
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(target.getControllerId(), PAGE)).hasSize(1);
|
||||
assertThat(countActionStatusAll()).isEqualTo(actionStatusCount);
|
||||
assertThat(findActionStatusAll(PAGE).getContent())
|
||||
.haveAtLeast(minActionStatusCountInPage, new ActionStatusCondition(Status.RUNNING));
|
||||
assertThat(findActionStatusAll(PAGE).getContent()).haveAtLeast(minActionStatusCountInPage, new ActionStatusCondition(Status.RUNNING));
|
||||
}
|
||||
|
||||
private Target createTargetAndAssertNoActiveActions() {
|
||||
@@ -796,11 +780,11 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
final Optional<DistributionSet> ds,
|
||||
final TargetUpdateStatus updateStatus, final int activeActions,
|
||||
final Optional<DistributionSet> installedDs) {
|
||||
final Target myT = targetManagement.getByControllerId(DdiDeploymentBaseTest.DEFAULT_CONTROLLER_ID).get();
|
||||
final Target myT = targetManagement.getByControllerId(DdiDeploymentBaseTest.DEFAULT_CONTROLLER_ID);
|
||||
assertThat(myT.getUpdateStatus()).isEqualTo(updateStatus);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(myT.getControllerId(), PAGE)).hasSize(activeActions);
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(myT.getControllerId())).isEqualTo(ds);
|
||||
assertThat(deploymentManagement.getInstalledDistributionSet(myT.getControllerId())).isEqualTo(installedDs);
|
||||
assertThat(deploymentManagement.findAssignedDistributionSet(myT.getControllerId())).isEqualTo(ds);
|
||||
assertThat(deploymentManagement.findInstalledDistributionSet(myT.getControllerId())).isEqualTo(installedDs);
|
||||
}
|
||||
|
||||
private void assertTargetCountByStatus(final int pending, final int error, final int inSync) {
|
||||
@@ -811,16 +795,26 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
private void assertActionStatusCount(final int total, final int running, final int warning, final int finished, final int canceled) {
|
||||
assertThat(countActionStatusAll()).isEqualTo(total);
|
||||
assertThat(findActionStatusAll(PAGE).getContent()).haveAtLeast(running, new ActionStatusCondition(Status.RUNNING));
|
||||
assertThat(findActionStatusAll(PAGE).getContent()).haveAtLeast(warning, new ActionStatusCondition(Status.WARNING));
|
||||
assertThat(findActionStatusAll(PAGE).getContent()).haveAtLeast(canceled, new ActionStatusCondition(Status.CANCELED));
|
||||
assertThat(findActionStatusAll(PAGE).getContent()).haveAtLeast(finished, new ActionStatusCondition(Status.FINISHED));
|
||||
assertThat(findActionStatusAll(PAGE).getContent()).satisfies(findActionStatusAll -> {
|
||||
assertThat(findActionStatusAll).haveAtLeast(running, new ActionStatusCondition(Status.RUNNING));
|
||||
assertThat(findActionStatusAll).haveAtLeast(warning, new ActionStatusCondition(Status.WARNING));
|
||||
assertThat(findActionStatusAll).haveAtLeast(canceled, new ActionStatusCondition(Status.CANCELED));
|
||||
assertThat(findActionStatusAll).haveAtLeast(finished, new ActionStatusCondition(Status.FINISHED));
|
||||
});
|
||||
}
|
||||
|
||||
private void assertLastTargetQueryUpdated(final long current) {
|
||||
assertThat(targetManagement.getByControllerId(DEFAULT_CONTROLLER_ID)).satisfies(target -> {
|
||||
assertThat(target.getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(target.getLastTargetQuery()).isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
});
|
||||
}
|
||||
|
||||
private void assertStatusAndActiveActionsCount(final TargetUpdateStatus status, final int activeActions) {
|
||||
final Target target = targetManagement.getByControllerId(DdiDeploymentBaseTest.DEFAULT_CONTROLLER_ID).get();
|
||||
assertThat(target.getUpdateStatus()).isEqualTo(status);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(target.getControllerId(), PAGE)).hasSize(activeActions);
|
||||
assertThat(targetManagement.getByControllerId(DdiDeploymentBaseTest.DEFAULT_CONTROLLER_ID)).satisfies(target -> {
|
||||
assertThat(target.getUpdateStatus()).isEqualTo(status);
|
||||
assertThat(deploymentManagement.findActiveActionsByTarget(target.getControllerId(), PAGE)).hasSize(activeActions);
|
||||
});
|
||||
}
|
||||
|
||||
private Page<ActionStatus> findActionStatusAll(final Pageable pageable) {
|
||||
|
||||
@@ -109,7 +109,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
// update assigned version
|
||||
putInstalledBase(target.getControllerId(), getJsonInstalledBase(ds.getName(), ds.getVersion()), status().isCreated());
|
||||
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get().getId()).isEqualTo(ds.getId());
|
||||
assertThat(deploymentManagement.findAssignedDistributionSet(target.getControllerId()).get().getId()).isEqualTo(ds.getId());
|
||||
|
||||
// update assigned version while version already assigned
|
||||
putInstalledBase(target.getControllerId(), getJsonInstalledBase(ds.getName(), ds.getVersion()), status().isOk());
|
||||
@@ -127,7 +127,7 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
|
||||
// get installed base
|
||||
putInstalledBase(target.getControllerId(), getJsonInstalledBase(dsName, dsVersion), status().isNotFound());
|
||||
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).isEmpty()).isTrue();
|
||||
assertThat(deploymentManagement.findAssignedDistributionSet(target.getControllerId()).isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
package org.eclipse.hawkbit.ddi.rest.resource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.eclipse.hawkbit.im.authentication.SpRole.CONTROLLER_ROLE_ANONYMOUS;
|
||||
import static org.eclipse.hawkbit.im.authentication.SpPermission.TENANT_CONFIGURATION;
|
||||
import static org.eclipse.hawkbit.im.authentication.SpRole.CONTROLLER_ROLE_ANONYMOUS;
|
||||
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.callAs;
|
||||
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.getAs;
|
||||
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.withController;
|
||||
@@ -125,7 +125,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
final String knownTargetControllerId = "target1";
|
||||
final String knownCreatedBy = "knownPrincipal";
|
||||
testdataFactory.createTarget(knownTargetControllerId);
|
||||
final Target findTargetByControllerID = targetManagement.getByControllerId(knownTargetControllerId).get();
|
||||
final Target findTargetByControllerID = targetManagement.getByControllerId(knownTargetControllerId);
|
||||
assertThat(findTargetByControllerID.getCreatedBy()).isEqualTo(knownCreatedBy);
|
||||
// make a poll, audit information should not be changed, run as controller principal!
|
||||
callAs(withController("controller", CONTROLLER_ROLE_ANONYMOUS),
|
||||
@@ -136,7 +136,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
return null;
|
||||
});
|
||||
// verify that audit information has not changed
|
||||
final Target targetVerify = targetManagement.getByControllerId(knownTargetControllerId).get();
|
||||
final Target targetVerify = targetManagement.getByControllerId(knownTargetControllerId);
|
||||
assertThat(targetVerify.getCreatedBy()).isEqualTo(findTargetByControllerID.getCreatedBy());
|
||||
assertThat(targetVerify.getCreatedAt()).isEqualTo(findTargetByControllerID.getCreatedAt());
|
||||
assertThat(targetVerify.getLastModifiedBy()).isEqualTo(findTargetByControllerID.getLastModifiedBy());
|
||||
@@ -170,10 +170,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")));
|
||||
assertThat(targetManagement.getByControllerId(controllerId).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerId(controllerId).get().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.REGISTERED);
|
||||
assertThat(targetManagement.getByControllerId(controllerId)).satisfies(target -> {
|
||||
assertThat(target.getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(target.getUpdateStatus()).isEqualTo(TargetUpdateStatus.REGISTERED);
|
||||
});
|
||||
|
||||
// not allowed methods
|
||||
mvc.perform(post(CONTROLLER_BASE, "default-tenant", controllerId))
|
||||
@@ -265,7 +265,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isNotModified());
|
||||
|
||||
final Target target = targetManagement.getByControllerId(controllerId).get();
|
||||
final Target target = targetManagement.getByControllerId(controllerId);
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
assignDistributionSet(ds.getId(), controllerId);
|
||||
|
||||
@@ -338,19 +338,18 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
void rootRsPreCommissioned() throws Exception {
|
||||
final String controllerId = "4711";
|
||||
testdataFactory.createTarget(controllerId);
|
||||
assertThat(targetManagement.getByControllerId(controllerId).get().getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
assertThat(targetManagement.getByControllerId(controllerId).getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
|
||||
final long current = System.currentTimeMillis();
|
||||
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:01:00")));
|
||||
assertThat(targetManagement.getByControllerId(controllerId).get().getLastTargetQuery())
|
||||
.isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(targetManagement.getByControllerId(controllerId).get().getLastTargetQuery())
|
||||
.isGreaterThanOrEqualTo(current);
|
||||
assertThat(targetManagement.getByControllerId(controllerId).get().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.REGISTERED);
|
||||
assertThat(targetManagement.getByControllerId(controllerId)).satisfies(target -> {
|
||||
assertThat(target.getLastTargetQuery()).isLessThanOrEqualTo(System.currentTimeMillis());
|
||||
assertThat(target.getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
||||
assertThat(target.getUpdateStatus()).isEqualTo(TargetUpdateStatus.REGISTERED);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -374,12 +373,13 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
return null;
|
||||
});
|
||||
// verify
|
||||
final Target target = targetManagement.getByControllerId(knownControllerId1).get();
|
||||
assertThat(target.getAddress()).isEqualTo(IpUtil.createHttpUri("127.0.0.1").toString());
|
||||
assertThat(target.getCreatedBy()).isEqualTo("CONTROLLER_PLUG_AND_PLAY");
|
||||
assertThat(target.getCreatedAt()).isGreaterThanOrEqualTo(create);
|
||||
assertThat(target.getLastModifiedBy()).isEqualTo("CONTROLLER_PLUG_AND_PLAY");
|
||||
assertThat(target.getLastModifiedAt()).isGreaterThanOrEqualTo(create);
|
||||
assertThat(targetManagement.getByControllerId(knownControllerId1)).satisfies(target -> {
|
||||
assertThat(target.getAddress()).isEqualTo(IpUtil.createHttpUri("127.0.0.1").toString());
|
||||
assertThat(target.getCreatedBy()).isEqualTo("CONTROLLER_PLUG_AND_PLAY");
|
||||
assertThat(target.getCreatedAt()).isGreaterThanOrEqualTo(create);
|
||||
assertThat(target.getLastModifiedBy()).isEqualTo("CONTROLLER_PLUG_AND_PLAY");
|
||||
assertThat(target.getLastModifiedAt()).isGreaterThanOrEqualTo(create);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,7 +397,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
// verify
|
||||
final Target target = targetManagement.getByControllerId(knownControllerId1).get();
|
||||
final Target target = targetManagement.getByControllerId(knownControllerId1);
|
||||
assertThat(target.getAddress()).isEqualTo(IpUtil.createHttpUri("***").toString());
|
||||
securityProperties.getClients().setTrackRemoteIp(true);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.hawkbit</groupId>
|
||||
<artifactId>hawkbit-artifact-repository-filesystem</artifactId>
|
||||
<artifactId>hawkbit-artifact-fs</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
Reference in New Issue
Block a user