hawkBit rest docs (management & DDI API) (#688)

* hawkBit REST docs.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Fiy gitignore.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Add to website.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Switch to generated docs.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Fix typos.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Review findings.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Otimizations.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Revert accidental checkin.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Add security link.
This commit is contained in:
Kai Zimmermann
2018-05-24 16:10:01 +02:00
committed by GitHub
parent 7126d68f31
commit 428e3af2bc
244 changed files with 11636 additions and 430 deletions

View File

@@ -0,0 +1,16 @@
# Eclipse.IoT hawkBit - Direct Device Integration API - Model and Resources
The Direct Device Integration (DDI) API is used by devices for communicating with the HawkBit Update Server through HTTP.
# Version 1
The model follows [semantic versioning](http://semver.org) with MAJOR version, i.e. breaking changes will result in a new MAJOR version.
# Compile
#### Build hawkbit-ddi-api
```
$ cd hawkbit/hawkbit-ddi-api
$ mvn clean install
```

View File

@@ -0,0 +1,37 @@
<!--
Copyright (c) 2015 Bosch Software Innovations GmbH and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
-->
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-rest-parent</artifactId>
<version>0.2.0-SNAPSHOT</version>
</parent>
<artifactId>hawkbit-ddi-api</artifactId>
<name>hawkBit :: REST :: DDI API</name>
<dependencies>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,82 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* <p>
* After the HawkBit Target has executed an action, received by a GET(URL)
* request it reports the completion of it to the HawkBit Server with a action
* status message, i.e. with a PUT message to the feedback channel, i.e. PUT
* URL/feedback. This message could be used not only at the end of execution but
* also as status updates during a longer lasting execution period. The format
* of each action answer message is defined below at each action. But it is
* expected, that the contents of the message answers have all a similar
* structure: The content starts with a generic header and additional elements.
* *
* </p>
*
* <p>
* The answer header would look like: { "id": "51659181", "time":
* "20140511T121314", "status": { "execution": "closed", "result": { "final":
* "success", "progress": {} } "details": [], } }
* </p>
*
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class DdiActionFeedback {
private final Long id;
private final String time;
@NotNull
@Valid
private final DdiStatus status;
/**
* Constructor.
*
* @param id
* of the actions the feedback is for
* @param time
* of the feedback
* @param status
* is the feedback itself
*/
@JsonCreator
public DdiActionFeedback(@JsonProperty("id") final Long id, @JsonProperty("time") final String time,
@JsonProperty("status") final DdiStatus status) {
this.id = id;
this.time = time;
this.status = status;
}
public Long getId() {
return id;
}
public String getTime() {
return time;
}
public DdiStatus getStatus() {
return status;
}
@Override
public String toString() {
return "ActionFeedback [id=" + id + ", time=" + time + ", status=" + status + "]";
}
}

View File

@@ -0,0 +1,55 @@
/**
* Copyright (c) Siemens AG, 2017
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import java.util.List;
import org.eclipse.hawkbit.ddi.rest.api.DdiRootControllerRestApi;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
/**
* Provide action history information to the controller as part of response to
* {@link DdiRootControllerRestApi#getControllerBasedeploymentAction}: 1.
* Current action status at the server; 2. List of messages from action history
* that were sent to server earlier by the controller using
* {@link DdiActionFeedback}.
*/
@JsonPropertyOrder({ "status", "messages" })
public class DdiActionHistory {
@JsonProperty("status")
private final String actionStatus;
@JsonProperty("messages")
private final List<String> messages;
/**
* Parameterized constructor for creating {@link DdiActionHistory}.
*
* @param actionStatus
* is the current action status at the server
* @param messages
* is a list of messages retrieved from action history.
*/
@JsonCreator
public DdiActionHistory(@JsonProperty("status") final String actionStatus,
@JsonProperty("messages") List<String> messages) {
this.actionStatus = actionStatus;
this.messages = messages;
}
@Override
public String toString() {
return "Action history [" + "status=" + actionStatus + ", messages={" + messages.toString() + "}]";
}
}

View File

@@ -0,0 +1,57 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import javax.validation.constraints.NotNull;
import org.springframework.hateoas.ResourceSupport;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Download information for all artifacts related to a specific {@link DdiChunk}
* .
*/
public class DdiArtifact extends ResourceSupport {
@NotNull
@JsonProperty
private String filename;
@JsonProperty
private DdiArtifactHash hashes;
@JsonProperty
private Long size;
public DdiArtifactHash getHashes() {
return hashes;
}
public void setHashes(final DdiArtifactHash hashes) {
this.hashes = hashes;
}
public String getFilename() {
return filename;
}
public void setFilename(final String fileName) {
filename = fileName;
}
public Long getSize() {
return size;
}
public void setSize(final Long size) {
this.size = size;
}
}

View File

@@ -0,0 +1,58 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Hashes for given Artifact.
*
*
*/
public class DdiArtifactHash {
@JsonProperty
private String sha1;
@JsonProperty
private String md5;
/**
* Default constructor.
*/
public DdiArtifactHash() {
// needed for json create
}
/**
* Public constructor.
*
* @param sha1
* @param md5
*/
public DdiArtifactHash(final String sha1, final String md5) {
this.sha1 = sha1;
this.md5 = md5;
}
/**
* @return the sha1
*/
public String getSha1() {
return sha1;
}
/**
* @return the md5
*/
public String getMd5() {
return md5;
}
}

View File

@@ -0,0 +1,49 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import javax.validation.constraints.NotNull;
/**
* Cancel action to be provided to the target.
*/
public class DdiCancel {
private final String id;
@NotNull
private final DdiCancelActionToStop cancelAction;
/**
* Parameterized constructor.
*
* @param id
* of the cancel action
* @param cancelAction
* the action
*/
public DdiCancel(final String id, final DdiCancelActionToStop cancelAction) {
this.id = id;
this.cancelAction = cancelAction;
}
public String getId() {
return id;
}
public DdiCancelActionToStop getCancelAction() {
return cancelAction;
}
@Override
public String toString() {
return "Cancel [id=" + id + ", cancelAction=" + cancelAction + "]";
}
}

View File

@@ -0,0 +1,40 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import javax.validation.constraints.NotNull;
/**
* The action that has to be stopped by the target.
*/
public class DdiCancelActionToStop {
@NotNull
private final String stopId;
/**
* Parameterized constructor.
*
* @param stopId
* ID of the action to be stoppedW
*/
public DdiCancelActionToStop(final String stopId) {
this.stopId = stopId;
}
public String getStopId() {
return stopId;
}
@Override
public String toString() {
return "CancelAction [stopId=" + stopId + "]";
}
}

View File

@@ -0,0 +1,94 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import java.util.Collections;
import java.util.List;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Deployment chunks.
*/
public class DdiChunk {
@JsonProperty("part")
@NotNull
private String part;
@JsonProperty("version")
@NotNull
private String version;
@JsonProperty("name")
@NotNull
private String name;
@JsonProperty("artifacts")
private List<DdiArtifact> artifacts;
@JsonProperty("metadata")
@JsonInclude(JsonInclude.Include.NON_NULL)
private List<DdiMetadata> metadata;
public DdiChunk() {
// needed for json create
}
/**
* Constructor.
*
* @param part
* of the deployment chunk
* @param version
* of the artifact
* @param name
* of the artifact
* @param artifacts
* download information
* @param metadata
* optional as additional information for the target/device
*/
public DdiChunk(final String part, final String version, final String name, final List<DdiArtifact> artifacts,
final List<DdiMetadata> metadata) {
this.part = part;
this.version = version;
this.name = name;
this.artifacts = artifacts;
this.metadata = metadata;
}
public String getPart() {
return part;
}
public String getVersion() {
return version;
}
public String getName() {
return name;
}
public List<DdiArtifact> getArtifacts() {
if (artifacts == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(artifacts);
}
public List<DdiMetadata> getMetadata() {
return metadata;
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Standard configuration for the target.
*/
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class DdiConfig {
@JsonProperty
private DdiPolling polling;
/**
* Constructor.
*
* @param polling
* configuration of the SP target
*/
public DdiConfig(final DdiPolling polling) {
this.polling = polling;
}
/**
* Constructor.
*/
public DdiConfig() {
// needed for json create.
}
public DdiPolling getPolling() {
return polling;
}
}

View File

@@ -0,0 +1,63 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import java.util.Map;
import javax.validation.constraints.NotEmpty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Feedback channel for ConfigData action.
*/
public class DdiConfigData extends DdiActionFeedback {
@NotEmpty
private final Map<String, String> data;
private final DdiUpdateMode mode;
/**
* Constructor.
*
* @param id
* of the actions the feedback is for
* @param time
* of the feedback
* @param status
* is the feedback itself
* @param data
* contains the attributes.
*/
@JsonCreator
public DdiConfigData(@JsonProperty(value = "id") final Long id, @JsonProperty(value = "time") final String time,
@JsonProperty(value = "status") final DdiStatus status,
@JsonProperty(value = "data") final Map<String, String> data,
@JsonProperty(value = "mode") final DdiUpdateMode mode) {
super(id, time, status);
this.data = data;
this.mode = mode;
}
public Map<String, String> getData() {
return data;
}
public DdiUpdateMode getMode() {
return mode;
}
@Override
public String toString() {
return "ConfigData [data=" + data + ", mode=" + mode + ", toString()=" + super.toString() + "]";
}
}

View File

@@ -0,0 +1,46 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import org.springframework.hateoas.ResourceSupport;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* {@link DdiControllerBase} resource content.
*/
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class DdiControllerBase extends ResourceSupport {
@JsonProperty
private DdiConfig config;
/**
* Constructor.
*
* @param config
* configuration of the SP target
*/
public DdiControllerBase(final DdiConfig config) {
this.config = config;
}
public DdiControllerBase() {
// needed for json create
}
public DdiConfig getConfig() {
return config;
}
}

View File

@@ -0,0 +1,158 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import java.util.Collections;
import java.util.List;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
/**
* Detailed update action information.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DdiDeployment {
private HandlingType download;
private HandlingType update;
@JsonProperty("chunks")
@NotNull
private List<DdiChunk> chunks;
private DdiMaintenanceWindowStatus maintenanceWindow;
/**
* Constructor.
*/
public DdiDeployment() {
// needed for json create.
}
/**
* Constructor.
*
* @param download
* handling type
* @param update
* handling type
* @param chunks
* to handle.
* @param maintenanceWindow
* specifying whether there is a maintenance schedule associated.
* If it is, the value is either 'available' (i.e. the
* 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
* 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,
final DdiMaintenanceWindowStatus maintenanceWindow) {
this.download = download;
this.update = update;
this.chunks = chunks;
this.maintenanceWindow = maintenanceWindow;
}
public HandlingType getDownload() {
return download;
}
public HandlingType getUpdate() {
return update;
}
public List<DdiChunk> getChunks() {
if (chunks == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(chunks);
}
public DdiMaintenanceWindowStatus getMaintenanceWindow() {
return this.maintenanceWindow;
}
/**
* The handling type for the update action.
*/
public enum HandlingType {
/**
* Not necessary for the command.
*/
SKIP("skip"),
/**
* Try to execute (local applications may intervene by SP control API).
*/
ATTEMPT("attempt"),
/**
* Execution independent of local intervention attempts.
*/
FORCED("forced");
private String name;
HandlingType(final String name) {
this.name = name;
}
@JsonValue
public String getName() {
return name;
}
}
/**
* Status of the maintenance window for action.
*/
public enum DdiMaintenanceWindowStatus {
/**
* A window is currently available, target can go ahead with
* installation.
*/
AVAILABLE("available"),
/**
* A window is not available, target should wait and skip the
* installation.
*/
UNAVAILABLE("unavailable");
private String status;
DdiMaintenanceWindowStatus(final String status) {
this.status = status;
}
/**
* @return status of maintenance window.
*/
@JsonValue
public String getStatus() {
return this.status;
}
}
@Override
public String toString() {
return "Deployment [download=" + download + ", update=" + update + ", chunks=" + chunks
+ (maintenanceWindow == null ? "]" : (", maintenanceWindow=" + maintenanceWindow + "]"));
}
}

View File

@@ -0,0 +1,82 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import javax.validation.constraints.NotNull;
import org.springframework.hateoas.ResourceSupport;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
/**
* Update action resource.
*/
@JsonPropertyOrder({ "id", "deployment", "actionHistory" })
public class DdiDeploymentBase extends ResourceSupport {
@JsonProperty("id")
@NotNull
private final String deplyomentId;
@JsonProperty("deployment")
@NotNull
private final DdiDeployment deployment;
/**
* Action history containing current action status and a list of feedback
* messages received earlier from the controller.
*/
@JsonProperty("actionHistory")
@JsonInclude(JsonInclude.Include.NON_NULL)
private final DdiActionHistory actionHistory;
/**
* Constructor.
*
* @param id
* of the update action
* @param deployment
* details
* @param actionHistory
* containing current action status and a list of feedback
* messages received earlier from the controller.
*/
@JsonCreator
public DdiDeploymentBase(@JsonProperty("id") final String id,
@JsonProperty("deplyomentId") final DdiDeployment deployment,
@JsonProperty("actionHistory") final DdiActionHistory actionHistory) {
this.deplyomentId = id;
this.deployment = deployment;
this.actionHistory = actionHistory;
}
public DdiDeployment getDeployment() {
return deployment;
}
/**
* Returns the action history containing current action status and a list of
* feedback messages received earlier from the controller.
*
* @return {@link DdiActionHistory}
*/
public DdiActionHistory getActionHistory() {
return actionHistory;
}
@Override
public String toString() {
return "DeploymentBase [id=" + deplyomentId + ", deployment=" + deployment + " actionHistory="
+ actionHistory + "]";
}
}

View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Additional metadata to be provided for the target/device.
*
*/
public class DdiMetadata {
@JsonProperty
@NotNull
private final String key;
@JsonProperty
@NotNull
private final String value;
public DdiMetadata(final String key, final String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,48 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Polling interval for the SP target.
*/
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class DdiPolling {
@JsonProperty
private String sleep;
/**
* Constructor.
*
* @param sleep
* between polls
*/
public DdiPolling(final String sleep) {
this.sleep = sleep;
}
/**
* Constructor.
*
*/
public DdiPolling() {
// needed for json create
}
public String getSleep() {
return sleep;
}
}

View File

@@ -0,0 +1,54 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Action fulfillment progress by means of gives the achieved amount of maximal
* of possible levels.
*/
public class DdiProgress {
@NotNull
private final Integer cnt;
private final Integer of;
/**
* Constructor.
*
* @param cnt
* achieved amount
* @param of
* maximum levels
*/
@JsonCreator
public DdiProgress(@JsonProperty("cnt") final Integer cnt, @JsonProperty("of") final Integer of) {
this.cnt = cnt;
this.of = of;
}
public Integer getCnt() {
return cnt;
}
public Integer getOf() {
return of;
}
@Override
public String toString() {
return "Progress [cnt=" + cnt + ", of=" + of + "]";
}
}

View File

@@ -0,0 +1,90 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
/**
* Result information of the action progress which can by an intermediate or
* final update.
*/
public class DdiResult {
@NotNull
@Valid
private final FinalResult finished;
private final DdiProgress progress;
/**
* Constructor.
*
* @param finished
* as final result
* @param progress
* if not yet finished
*/
@JsonCreator
public DdiResult(@JsonProperty("finished") final FinalResult finished,
@JsonProperty("progress") final DdiProgress progress) {
this.finished = finished;
this.progress = progress;
}
public FinalResult getFinished() {
return finished;
}
public DdiProgress getProgress() {
return progress;
}
/**
* Defined status of the final result.
*
*/
public enum FinalResult {
/**
* Execution was successful.
*/
SUCESS("success"),
/**
* Execution terminated with errors or without the expected result.
*/
FAILURE("failure"),
/**
* No final result could be determined (yet).
*/
NONE("none");
private String name;
FinalResult(final String name) {
this.name = name;
}
@JsonValue
public String getName() {
return name;
}
}
@Override
public String toString() {
return "Result [finished=" + finished + ", progress=" + progress + "]";
}
}

View File

@@ -0,0 +1,133 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.json.model;
import java.util.Collections;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
/**
* Details status information concerning the action processing.
*/
public class DdiStatus {
@NotNull
@Valid
private final ExecutionStatus execution;
@NotNull
@Valid
private final DdiResult result;
private final List<String> details;
/**
* Constructor.
*
* @param execution
* status
* @param result
* information
* @param details
* as optional addition
*/
@JsonCreator
public DdiStatus(@JsonProperty("execution") final ExecutionStatus execution,
@JsonProperty("result") final DdiResult result, @JsonProperty("details") final List<String> details) {
this.execution = execution;
this.result = result;
this.details = details;
}
public ExecutionStatus getExecution() {
return execution;
}
public DdiResult getResult() {
return result;
}
public List<String> getDetails() {
if (details == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(details);
}
/**
* The element status contains information about the execution of the
* operation.
*
*/
public enum ExecutionStatus {
/**
* Execution of the action has finished.
*/
CLOSED("closed"),
/**
* Execution has started but has not yet finished.
*/
PROCEEDING("proceeding"),
/**
* Execution was suspended from outside.
*/
CANCELED("canceled"),
/**
* Action has been noticed and is intended to run.
*/
SCHEDULED("scheduled"),
/**
* Action was not accepted.
*/
REJECTED("rejected"),
/**
* Action is started after a reset, power loss, etc.
*/
RESUMED("resumed"),
/**
* The action has been downloaded by the target.
*/
DOWNLOADED("downloaded"),
/**
* Target starts to download.
*/
DOWNLOAD("download");
private String name;
ExecutionStatus(final String name) {
this.name = name;
}
@JsonValue
public String getName() {
return name;
}
}
@Override
public String toString() {
return "Status [execution=" + execution + ", result=" + result + ", details=" + details + "]";
}
}

View File

@@ -0,0 +1,48 @@
/**
* Copyright (c) 2018 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
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.
*
* @see DdiConfigData
*/
public enum DdiUpdateMode {
/**
* Merge update strategy
*/
MERGE("merge"),
/**
* Replacement update strategy
*/
REPLACE("replace"),
/**
* Removal update strategy
*/
REMOVE("remove");
private String name;
DdiUpdateMode(final String name) {
this.name = name;
}
@JsonValue
public String getName() {
return name;
}
}

View File

@@ -0,0 +1,56 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.rest.api;
/**
* Constants for the direct device integration rest resources.
*/
public final class DdiRestConstants {
/**
* The base URL mapping of the direct device integration rest resources.
*/
public static final String BASE_V1_REQUEST_MAPPING = "/{tenant}/controller/v1";
/**
* Deployment action resources.
*/
public static final String DEPLOYMENT_BASE_ACTION = "deploymentBase";
/**
* Cancel action resources.
*/
public static final String CANCEL_ACTION = "cancelAction";
/**
* Feedback channel.
*/
public static final String FEEDBACK = "feedback";
/**
* File suffix for MDH hash download (see Linux md5sum).
*/
public static final String ARTIFACT_MD5_DWNL_SUFFIX = ".MD5SUM";
/**
* Config data action resources.
*/
public static final String CONFIG_DATA_ACTION = "configData";
/**
* Default value specifying that no action history to be sent as part of
* response to deploymentBase
* {@link DdiRootControllerRestApi#getControllerBasedeploymentAction}.
*/
public static final String NO_ACTION_HISTORY = "0";
private DdiRestConstants() {
// constant class, private constructor.
}
}

View File

@@ -0,0 +1,250 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.ddi.rest.api;
import java.io.InputStream;
import java.lang.annotation.Target;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import org.eclipse.hawkbit.ddi.json.model.DdiActionFeedback;
import org.eclipse.hawkbit.ddi.json.model.DdiArtifact;
import org.eclipse.hawkbit.ddi.json.model.DdiCancel;
import org.eclipse.hawkbit.ddi.json.model.DdiConfigData;
import org.eclipse.hawkbit.ddi.json.model.DdiControllerBase;
import org.eclipse.hawkbit.ddi.json.model.DdiDeploymentBase;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* REST resource handling for root controller CRUD operations.
*/
@RequestMapping(DdiRestConstants.BASE_V1_REQUEST_MAPPING)
public interface DdiRootControllerRestApi {
/**
* Returns all artifacts of a given software module and target.
*
* @param tenant
* of the client
* @param controllerId
* of the target that matches to controller id
* @param softwareModuleId
* of the software module
* @return the response
*/
@RequestMapping(method = RequestMethod.GET, value = "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts", produces = {
MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
ResponseEntity<List<DdiArtifact>> getSoftwareModulesArtifacts(@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") final String controllerId,
@PathVariable("softwareModuleId") final Long softwareModuleId);
/**
* Root resource for an individual {@link Target}.
*
* @param tenant
* of the request
* @param controllerId
* of the target that matches to controller id
* @param request
* the HTTP request injected by spring
* @return the response
*/
@RequestMapping(method = RequestMethod.GET, value = "/{controllerId}", produces = { MediaTypes.HAL_JSON_VALUE,
MediaType.APPLICATION_JSON_VALUE })
ResponseEntity<DdiControllerBase> getControllerBase(@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") final String controllerId);
/**
* Handles GET {@link DdiArtifact} download request. This could be full or
* partial (as specified by RFC7233 (Range Requests)) download request.
*
* @param tenant
* of the request
* @param controllerId
* of the target
* @param softwareModuleId
* of the parent software module
* @param fileName
* of the related local artifact
* @param response
* of the servlet
* @param request
* from the client
*
* @return response of the servlet which in case of success is status code
* {@link HttpStatus#OK} or in case of partial download
* {@link HttpStatus#PARTIAL_CONTENT}.
*/
@RequestMapping(method = RequestMethod.GET, value = "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{fileName}")
ResponseEntity<InputStream> downloadArtifact(@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") final String controllerId,
@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("fileName") final String fileName);
/**
* Handles GET {@link DdiArtifact} MD5 checksum file download request.
*
* @param tenant
* of the request
* @param controllerId
* of the target
* @param softwareModuleId
* of the parent software module
* @param fileName
* of the related local artifact
* @param response
* of the servlet
* @param request
* the HTTP request injected by spring
*
* @return {@link ResponseEntity} with status {@link HttpStatus#OK} if
* successful
*/
@RequestMapping(method = RequestMethod.GET, value = "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{fileName}"
+ DdiRestConstants.ARTIFACT_MD5_DWNL_SUFFIX, produces = MediaType.TEXT_PLAIN_VALUE)
ResponseEntity<Void> downloadArtifactMd5(@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") final String controllerId,
@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("fileName") final String fileName);
/**
* Resource for software module.
*
* @param tenant
* of the request
* @param controllerId
* of the target
* @param actionId
* of the {@link DdiDeploymentBase} that matches to active
* actions.
* @param resource
* an hashcode of the resource which indicates if the action has
* been changed, e.g. from 'soft' to 'force' and 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}.
* actionHistoryMessageCount < 0, retrieves the maximum allowed
* number of action status messages from history;
* actionHistoryMessageCount = 0, does not retrieve any message;
* and actionHistoryMessageCount > 0, retrieves the specified
* number of messages, limited by maximum allowed number.
* @param request
* the HTTP request injected by spring
* @return the response
*/
@RequestMapping(value = "/{controllerId}/" + DdiRestConstants.DEPLOYMENT_BASE_ACTION
+ "/{actionId}", method = RequestMethod.GET, produces = { MediaTypes.HAL_JSON_VALUE,
MediaType.APPLICATION_JSON_VALUE })
ResponseEntity<DdiDeploymentBase> getControllerBasedeploymentAction(@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId,
@PathVariable("actionId") @NotEmpty final Long actionId,
@RequestParam(value = "c", required = false, defaultValue = "-1") final int resource,
@RequestParam(value = "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount);
/**
* This is the feedback channel for the {@link DdiDeploymentBase} action.
*
* @param tenant
* of the client
* @param feedback
* to provide
* @param controllerId
* of the target that matches to controller id
* @param actionId
* of the action we have feedback for
* @param request
* the HTTP request injected by spring
*
* @return the response
*/
@RequestMapping(value = "/{controllerId}/" + DdiRestConstants.DEPLOYMENT_BASE_ACTION + "/{actionId}/"
+ DdiRestConstants.FEEDBACK, method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Void> postBasedeploymentActionFeedback(@Valid final DdiActionFeedback feedback,
@PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId,
@PathVariable("actionId") @NotEmpty final Long actionId);
/**
* This is the feedback channel for the config data action.
*
* @param tenant
* of the client
* @param configData
* as body
* @param controllerId
* to provide data for
* @param request
* the HTTP request injected by spring
*
* @return status of the request
*/
@RequestMapping(value = "/{controllerId}/"
+ DdiRestConstants.CONFIG_DATA_ACTION, method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Void> putConfigData(@Valid final DdiConfigData configData,
@PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId);
/**
* RequestMethod.GET method for the {@link DdiCancel} action.
*
* @param tenant
* of the request
* @param controllerId
* ID of the calling target
* @param actionId
* of the action
* @param request
* the HTTP request injected by spring
*
* @return the {@link DdiCancel} response
*/
@RequestMapping(value = "/{controllerId}/" + DdiRestConstants.CANCEL_ACTION
+ "/{actionId}", method = RequestMethod.GET, produces = { MediaTypes.HAL_JSON_VALUE,
MediaType.APPLICATION_JSON_VALUE })
ResponseEntity<DdiCancel> getControllerCancelAction(@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId,
@PathVariable("actionId") @NotEmpty final Long actionId);
/**
* RequestMethod.POST method receiving the {@link DdiActionFeedback} from
* the target.
*
* @param tenant
* of the client
* @param feedback
* the {@link DdiActionFeedback} from the target.
* @param controllerId
* the ID of the calling target
* @param actionId
* of the action we have feedback for
* @param request
* the HTTP request injected by spring
*
* @return the {@link DdiActionFeedback} response
*/
@RequestMapping(value = "/{controllerId}/" + DdiRestConstants.CANCEL_ACTION + "/{actionId}/"
+ DdiRestConstants.FEEDBACK, method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Void> postCancelActionFeedback(@Valid final DdiActionFeedback feedback,
@PathVariable("tenant") final String tenant,
@PathVariable("controllerId") @NotEmpty final String controllerId,
@PathVariable("actionId") @NotEmpty final Long actionId);
}