# Update operation

Software and firmware update is the most complete operation OpenGate models: it is long-running,
multi-step, and its progress matters as much as its outcome. It is therefore a good example of the
[asynchronous flow with multiple responses](../../flows/#asynchronous-with-multiple-responses).

## Flow diagram

OpenGate suggests a complete flow covering all the possible stages of a device update. In the real world
a device may implement only part of these steps — any number and kind of steps implemented by your
device is supported.

```mermaid
sequenceDiagram
    participant OG as OpenGate connector
    participant Dev as Device

    OG->>Dev: Operation request (HTTP POST)
    Dev-->>OG: Response ACK (HTTP 200 OK)

    Note over OG,Dev: the device reports progress,<br>one notification per step

    Dev->>OG: STEP DOWNLOADFILE (0%)
    OG-->>Dev: ACK (HTTP 200 OK)
    Dev->>OG: STEP DOWNLOADFILE (x%)
    OG-->>Dev: ACK (HTTP 200 OK)
    Dev->>OG: STEP DOWNLOADFILE (100%)
    OG-->>Dev: ACK (HTTP 200 OK)
    Dev->>OG: STEP BEGINPREACTION
    OG-->>Dev: ACK (HTTP 200 OK)
    Dev->>OG: STEP ENDPREACTION
    OG-->>Dev: ACK (HTTP 200 OK)
    Dev->>OG: STEP BEGINPOSTACTION
    OG-->>Dev: ACK (HTTP 200 OK)
    Dev->>OG: STEP ENDPOSTACTION
    OG-->>Dev: ACK (HTTP 200 OK)
    Dev->>OG: STEP BEGININSTALL
    OG-->>Dev: ACK (HTTP 200 OK)
    Dev->>OG: STEP ENDINSTALL
    OG-->>Dev: ACK (HTTP 200 OK)
    Dev->>OG: STEP ENDUPDATE
    OG-->>Dev: ACK (HTTP 200 OK)
```

Each notification is an `HTTP POST` from the device carrying the operation response, and each ACK is
OpenGate's `HTTP 200` reply. Every notification updates the operation's `steps` array, so the north API
sees the download percentage advance in real time.

The `UPDATE` operation type declares the following steps: `ACCEPTED`, `BEGINUPDATE`, `DOWNLOADFILE`,
`BEGINPREACTION`, `ENDPREACTION`, `BEGININSTALL`, `ENDINSTALL`, `BEGINPOSTACTION`, `ENDPOSTACTION` and
`ENDUPDATE`. See the [status reference](../../status_reference/#step-result) for the results a step can
report.

### North API invocation

Back office applications invoke device update operations through the ordinary
[jobs API](../../jobs/) — everything you know about jobs applies. What is specific to updates is the
operation name and its parameters:

#### _Device Update Example_

```json
{
    "job" :
    {
        "request" : {
            "name" : "UPDATE",
            "parameters": [
                {
                    "name" : "bundleName",
                    "type":"string",
                    "value" : {
                        "string" : "bundle_1"
                    }
                },
                {
                    "name" : "bundleVersion",
                    "type":"string",
                    "value" : {
                        "string" : "1.0"
                    }
                }
            ],
            "active" : true,
            "notify" : true,
            "callback" : "http://[your_application_address]/[your_URI]",

            "schedule" : {
                "start" : {
                  "date" : "2012-09-10T12:33:43Z"
                },
                "stop" : {
                  "delayed" : 300000
                }
            },
            "operationParameters" : {
                "ackTimeout" : 5000,
                "timeout" : 6000,
                "retries" : 0,
                "retriesDelay" : 1000,
                "retryResultList" : ["ERROR_PROCESSING"]
            },
            "target" : {
                "append" : {
                    "entities" : [ "device_1", "device_2" ]
                }
            }
        }
    }
}
```

### South API invocation

This is the document the device receives from the platform. The `deploymentElements` array is what makes
an update different from any other operation: it tells the device what to download, where to put it, in
which order, and how to verify it.

See the [device integration section](../../../device_integration/http/operations/) for the endpoints and
transport details:

#### _Device Update Example_

```json
{
    "operation": {
        "request": {
            "timestamp": 1453822201099,
            "name": "UPDATE",
            "parameters": [
                {
                    "name": "bundleName",
                    "value": {
                        "string": "bundle_1"
                    }
                },
                {
                    "name": "bundleVersion",
                    "value": {
                        "string": "version_1"
                    }
                },
                {
                    "name": "deploymentElements",
                    "value": {
                        "array": [
                            {
                                "type": "FIRMWARE",
                                "downloadUrl": "http://[your_opengate_address]/bundles/74427c0c-a28c-4765-92ef-30010adb733d/1002/firmware-1_1.1.bin",
                                "path": "/home",
                                "order": 1,
                                "operation": "INSTALL",
                                "option": "OPTIONAL",
                                "validators": [
                                    {
                                        "type": "SHA-256",
                                        "value": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
                                    }
                                ],
                                "size": 18
                            }
                        ]
                    }
                }
            ],
            "id": "072b08d1-0fcb-4a0c-a2d8-99773f9b9327"
        }
    }
}
```
