You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Overview

Current DAC design assumes that AWC will behave as a proxy to LISA API and will be it's only consumer. Main reason for such decision was dictated by requirement of tracking and controlling LISA usage to prevent situation when application is currently started and external client (eg. DAC Manager) would call LISA's uninstall API. This would cause undefined behaviour, due to removal of application during active state. Covering LISA's API by AWC would prevent such situation by blocking uninstall request on AWC level.

Above approach unfortunately has cons:

  • Violates SRP, AWC should be only responsible for controlling application window(size, position) and state (start, stop).
  • It creates strong dependency between AWC and LISA.
  • Code bloat by providing unnecessary proxy layer.
  • LISA by design cannot be used standalone, and some external application manger needs to protect access to LISA to prevent above situation.

This design resolve this issue by extending LISA API with locking mechanism, decoupling it from AWC and expose LISA API to external clients.

Design

LISA API should be extended with three additional methods: lock, unlock. Those methods are used by entity which manages application state (AWC) to block any operations (uninstall) on application during it's active state (started, suspended). Lock is performed with id, version of the application, lock owner and lock reason, we are only blocking specific version of application.

After sending asynchronous request (uninstall) to LISA, requesting client (eg. DAC Manager), if application is currently used (active - locked by AWC), will receive error result with information about lock reason(eg. ERROR_APP_ACTIVE). Additional API method getLockInfo will allow to check who is the lock owner.

If application is not currently in locked state (is in stopped state) asynchronous operation can be performed.

From other end if AWC will receive Start (or initiate itself) request from MainUI, it should send lock signal to the LISA to prevent its uninstallation/update by external LISA's API client (eg. DAC Manager) during application active state. If lock request initiated by AWC succeeds application can be started, otherwise return error will be sent to the caller (MainUI) that application is in currently being processed (uninstall) by LISA.

Both scenarios and API change are described below.

API Extension

When LISA's client (DAC Manager, UI) will request to uninstall application which is currently used (locked) by AWC following error will be returned:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
{
  "code": 1009,
  "message": "ERROR_APP_ACTIVE"
}

Lock/Unlock calls should be used exclusively by AWC (for now, maybe other use cases will show up which require locking by DAC Manager eg batching)  just before transition to start and after transition to stop of the DAC application.

If AWC will try to activate (lock) application during ongoing uninstallation procedure, following error will be returned

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
{
  "code": 1010,
  "message": "ERROR_APP_UNINSTALLING"
}

By calling getLockInfo caller can receive more details about current lock owner and reason (for now there will be only 2 lisa and awc).

  • call getLockInfo from AWC → { "owner": "lisa", "reason": "uninstalling" }

  • call getLockInfo z DACM/UI -> { "owner": "awc", "reason": "active" }

API Schema


Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
{
  "$schema": "interface.schema.json",
  "jsonrpc": "2.0",
  "info": {
    "title": "Lisa API",
    "class": "Lisa",
    "description": "Lisa JSON-RPC interface",
    "version": "0.0.2"
  },
  "common": {
    "$ref": "common.json"
  },
  "methods": {
    "lock": {
      "summary": "Lock application",
      "description": "Lock and take control over application state until unlock is called",
      "params": {
        "type": "object",
        "properties": {
          "type": {
            "description": "Application type (mime-type)",
            "type": "string",
            "example": "application/vnd.rdk-app.dac.native"
          }, 
          "id": {
            "description": "id of the application, assumed reverse domain name notation, the id should match the [ASMS application id](https://wikiprojects.upc.biz/display/SPARK/ASMS+API+specification)",
            "type": "string",
            "example": "com.libertyglobal.app.awesome"
          },
          "version": {
            "description": "version of the application",
            "type": "string",
            "example": "1.0.0"
          },
          "owner": {
            "description": "Owner of the lock",
            "type": "string",
            "example": "awc"
          },
          "reason": {
            "description": "Reason for the lock",
            "type": "string",
            "example": "active"
          }
        },
        "required": [
          "type",
          "id",
          "version"
        ]
      },
      "result": {
        "type": "object",
        "properties": {
          "handle": {
            "type": "string",
            "example": "a76a9ad56769634dbbc9c54bac15ddb9"
          }
        },
        "required": [
          "handle"
        ]
      },
      "errors": [
        {
          "description": "WrongParams",
          "code": 1001,
          "message": "Request not accepted because of wrong parameters"
        },
        {
          "description": "Initializing",
          "code": 1004,
          "message": " LISA is performing initialization, wait for operationStatus event"
        },
        {
          "code": 1009,
          "message": "ERROR_APP_ACTIVE"
        },
        {
          "code": 1010,
          "message": "ERROR_APP_UNINSTALLING"
        }
      ]
    },
    "unlock": {
      "summary": "Unlock application",
      "description": "Unlock application and make it available to be used by other components",
      "params": {
        "type": "object",
        "properties": {
          "handle": {
            "type": "string",
            "example": "a76a9ad56769634dbbc9c54bac15ddb9"
          }
        },
        "required": [
          "handle"
        ]
      },
      "result": {
        "type": "object",
        "properties": {}
      },
      "errors": [
        {
          "description": "WrongParams",
          "code": 1001,
          "message": "Request not accepted because of wrong parameters"
        },
        {
          "description": "Initializing",
          "code": 1004,
          "message": " LISA is performing initialization, wait for operationStatus event"
        },
        {
          "description": "WrongHandle",
          "code": 1007,
          "message": "The handle is not correct, e.g. the operation has finished."
        }
      ]
    },
    "getLockInfo": {
      "summary": "Get lock details",
      "description": "Returns info about lock owner and lock reason",
      "params": {
        "type": "object",
        "properties": {
          "type": {
            "description": "Application type (mime-type)",
            "type": "string",
            "example": "application/vnd.rdk-app.dac.native"
          },  
          "id": {
            "description": "id of the application, assumed reverse domain name notation, the id should match the [ASMS application id](https://wikiprojects.upc.biz/display/SPARK/ASMS+API+specification)",
            "type": "string",
            "example": "com.libertyglobal.app.awesome"
          },
          "version": {
            "description": "version of the application",
            "type": "string",
            "example": "1.0.0"
          }
        },
        "required": [
          "type",
          "id",
          "version"
        ]
      },
      "result": {
        "type": "object",
        "properties": {
          "owner": {
            "description": "Owner of the lock",
            "type": "string",
            "example": "awc"
          },
          "reason": {
            "description": "Reason for the lock",
            "type": "string",
            "example": "active"
          }
        }
      },
      "errors": [
        {
          "description": "WrongParams",
          "code": 1001,
          "message": "Request not accepted because of wrong parameters"
        },
        {
          "description": "Initializing",
          "code": 1004,
          "message": " LISA is performing initialization, wait for operationStatus event"
        },
        {
          "description": "WrongHandle",
          "code": 1007,
          "message": "The handle is not correct, e.g. the operation has finished."
        }
      ]
    }
  },
  "events": {
    "operationStatus": {
      "summary": "Completion of asynchronous operation.",
      "description": "Notification sent on the completion of asynchronous operation.",
      "params": {
        "type": "object",
        "properties": {
          "handle": {
            "type": "string",
            "example": "4c4712a4141d261ec0ca8f9037950685"
          },
          "operation": {
            "description": "Operation producing the event (Installing, Uninstalling)",
            "type": "string",
            "example": "Installing"
          },
          "type": {
            "description": "Application type (mime-type)",
            "type": "string",
            "example": "application/vnd.rdk-app.dac.native"
          },  
          "id": {
            "description": "id of the application, assumed reverse domain name notation, the id should match the [ASMS application id](https://wikiprojects.upc.biz/display/SPARK/ASMS+API+specification)",
            "type": "string",
            "example": "com.libertyglobal.app.awesome"
          },
          "version": {
            "description": "version of the application",
            "type": "string",
            "example": "1.0.0"
          },
          "status": {
            "description": "Status of the operation (Success, Failed, Progress, Cancelled)",
            "type": "string",
            "example": "Success" 
          },
          "details": {
            "type": "string",
            "example": "Downloaded 2342 KB, unpacked 3233 KB"
          }
        },
        "required": [
          "handle",
          "operation",
          "type",
          "id",
          "version",
          "status"
        ]
      }
    }
  }
}

API Description

<!-- Generated automatically, DO NOT EDIT! -->

<a name="head.Version"></a>

Version

Version: 0.0.2

<a name="head.Description"></a>

Description

Lisa JSON-RPC interface.

<a name="head.Methods"></a>

Methods

<a name="method.lock"></a>

lock

Lock application.

Description

Lock and take control over application state until unlock is called

Parameters

NameTypeDescription
paramsobject
params.typestringApplication type (mime-type)
params.idstringid of the application, assumed reverse domain name notation, the id should match the ASMS application id
params.versionstringversion of the application
params?.ownerstring<sup>(optional)</sup> Owner of the lock
params?.reasonstring<sup>(optional)</sup> Reason for the lock (must be one of the following: active, installing, uninstalling)

Result

NameTypeDescription
resultobject
result.handlestring

Errors

CodeMessageDescription
1001Request not accepted because of wrong parametersWrongParams
1004LISA is performing initialization, wait for operationStatus eventInitializing
1009ERROR_APP_ACTIVE
1010ERROR_APP_UNINSTALLING

Example

Request

{
    "jsonrpc": "2.0",
    "id": 1234567890,
    "method": "Lisa.1.lock",
    "params": {
        "id": "com.libertyglobal.app.awesome",
        "version": "1.0.0",
        "owner": "awc",
        "reason": "active"
    }
}

Response

{
    "jsonrpc": "2.0",
    "id": 1234567890,
    "result": {
        "handle": "a76a9ad56769634dbbc9c54bac15ddb9"
    }
}

<a name="method.unlock"></a>

unlock

Unlock application.

Description

Unlock application and make it available to be used by other components

Parameters

NameTypeDescription
paramsobject
params.handlestring

Result

NameTypeDescription
resultobject

Errors

CodeMessageDescription
1001Request not accepted because of wrong parametersWrongParams
1004LISA is performing initialization, wait for operationStatus eventInitializing
1007The handle is not correct, e.g. the operation has finished.WrongHandle

Example

Request

{
    "jsonrpc": "2.0",
    "id": 1234567890,
    "method": "Lisa.1.unlock",
    "params": {
        "handle": "a76a9ad56769634dbbc9c54bac15ddb9"
    }
}

Response

{
    "jsonrpc": "2.0",
    "id": 1234567890,
    "result": {}
}

<a name="method.getLockInfo"></a>

getLockInfo

Get lock details.

Description

Returns info about lock owner and lock reason

Parameters

NameTypeDescription
paramsobject
params.typestringApplication type (mime-type)
params.idstringid of the application, assumed reverse domain name notation, the id should match the ASMS application id
params.versionstringversion of the application

Result

NameTypeDescription
resultobject
result?.ownerstring<sup>(optional)</sup> Owner of the lock
result?.reasonstring<sup>(optional)</sup> Reason for the lock (must be one of the following: active, installing, uninstalling)

Errors

CodeMessageDescription
1001Request not accepted because of wrong parametersWrongParams
1004LISA is performing initialization, wait for operationStatus eventInitializing
1007The handle is not correct, e.g. the operation has finished.WrongHandle

Example

Request

{
    "jsonrpc": "2.0",
    "id": 1234567890,
    "method": "Lisa.1.getLockInfo",
    "params": {
        "id": "com.libertyglobal.app.awesome",
        "version": "1.0.0"
    }
}

Response

{
    "jsonrpc": "2.0",
    "id": 1234567890,
    "result": {
        "owner": "awc",
        "reason": "active"
    }
}

<a name="head.Notifications"></a>

Notifications

Notifications are autonomous events, triggered by the internals of the implementation, and broadcasted via JSON-RPC to all registered observers.

<a name="event.operationStatus"></a>

operationStatus

Completion of asynchronous operation.

Description

Notification sent on the completion of asynchronous operation.

Parameters

NameTypeDescription
paramsobject
params.handlestring
params.operationstring(Installing, Uninstalling)
params.typestringApplication type (mime-type)
params.idstringid of the application, assumed reverse domain name notation, the id should match the ASMS application id
params.versionstringversion of the application
params.statusstring(Success, Failed, Progress, Cancelled)
params?.detailsstring<sup>(optional)</sup>

Example

{
    "jsonrpc": "2.0",
    "method": "client.events.1.operationStatus",
    "params": {
        "handle": "4c4712a4141d261ec0ca8f9037950685",
        "operation": "Installing",
        "type": "dac", 
        "id": "com.libertyglobal.app.awesome",
        "version": "1.0.0",
        "status": "Success",
        "details": "Downloaded 2342 KB, unpacked 3233 KB"
    }
}


Activity Diagram

Client initiated uninstallation

processUninstallUninstallerror: Application lockedtrueLock?falseUninstall

AWC Start/Stop 

processStart DACStarterror: Application not foundfalseApplication in Registry?trueLocksuccessfailStart Applicationerror: Application lockedprocessStop DACStoperror: Application not foundfalseApplication in Registry?trueStop ApplicationUnlock

Sequence Diagram

AWC DAC registry Initialization and Update

AWCLISA ContainerConfigurationConfigurationApplication ControllerApplication ControllerAppRegistryAppRegistryThunder RunnerThunder RunnerLISA PluginLISA PluginInitialisation1Construct/Initialize with defaults2"register 'operationStatus' notification listener"{"jsonrpc": "2.0","id": 0,"method": "LISA.1.register","params": {"event": "operationStatus","id": "events.awc.lisa.1"}}3read configuration4configloop[App list from conf]5AWC::ApplicationRegistry.addEntry(appId)loop[list of properties]6AWC::ApplicationRegistry.setProperty(appId,key,value)7getList8result <app_list>loop[App list from LISA]9AWC::ApplicationRegistry.addEntry(appId)loop[list of properties]10AWC::ApplicationRegistry.setProperty(appId,key,value)5 minutes later11install12operationStatus{"id": "1223","method": "events.awc.lisa.1.operationStatus","params": {"handle": "4c4712a4141d261ec0ca8f9037950685","operation": "Installed","id": "com.libertyglobal.app.extra","version": "1.0.0","status": "Success","details": "Downloaded 2342 KB, unpacked 3233 KB"}}13getList14result <app_list>loop[App list from LISA]15AWC::ApplicationRegistry.addEntry(appId)loop[list of properties]16AWC::ApplicationRegistry.setProperty(appId,key,value)

DAC Background Manager installation sequence

Application ServicesAWCLISAOperatorOperatorApplication ServicesApplication ServicesDAC Background ManagerDAC Background ManagerApplication ControllerApplication ControllerAppRegistryAppRegistryLISALISAOperator Triggered Installation"register 'operationStatus' notification listener"{"jsonrpc": "2.0","id": 0,"method": "LISA.1.register","params": {"event": "operationStatus","id": "events.dacbg.lisa.1"}}update configurationupdate configurationRequest metadataMetadatagetList{"jsonrpc": "2.0","id": "1223","method": "LISA.1.getList","params": {"category": "application"}}result <apps>check if installedloop[all appIds to be installed]Installation Procedureinstall{..."method": "LISA.1.install","params": {"type": "application/vnd.rdk-app.dac.native","id": "com.libertyglobal.awesine","version": "1.0.0","appName": "Awesome Application",...}}loop[periodically check progress]getProgress'{"jsonrpc": "2.0","id": "1223","method": "LISA.1.getProgress","params": {"handle": "a76a9ad56769634dbbc9c54bac15ddb9"}}result{"jsonrpc": "2.0","id": "1223","result": {"progress": 75}}5 minutes lateroperationStatus{"id": "1223","method": "events.dacbg.lisa.1.operationStatus","params": {"handle": "4c4712a4141d261ec0ca8f9037950685","operation": "Installed","id": "com.libertyglobal.app.awesome","version": "1.0.0","status": "Success","details": "Downloaded 2342 KB, unpacked 3233 KB"}}operationStatus{"id": "62","method": "events.awc.lisa.1.operationStatus","params": {"handle": "4c4712a4141d261ec0ca8f9037950685","operation": "Installed","id": "com.libertyglobal.app.awesome","version": "1.0.0","status": "Success","details": "Downloaded 2342 KB, unpacked 3233 KB"}}getList{"jsonrpc": "2.0","id": "1223","method": "LISA.1.getList","params": {"category": "application"}}result <app_list>loop[iterate through getList result]checkIfEntryExists(appId)trueAWC::ApplicationRegistry.addEntry(appId)loop[list of properties]AWC::ApplicationRegistry.setProperty(appId,key,value)finished

DAC Background Manager uninstallation sequence

Application ServicesAWCLISAOperatorOperatorApplication ServicesApplication ServicesDAC Background ManagerDAC Background ManagerApplication ControllerApplication ControllerAppRegistryAppRegistryLISALISAOperator Triggered Uninstallation"register 'operationStatus' notification listener"{"jsonrpc": "2.0","id": 0,"method": "LISA.1.register","params": {"event": "operationStatus","id": "events.dacbg.lisa.1"}}update configurationupdate configurationgetList{"jsonrpc": "2.0","id": "1223","method": "LISA.1.getList","params": {"category": "application"}}result <apps>check if installedUninstallation Procedureuninstall{..."method": "LISA.1.uninstall","params": {"type": "application/vnd.rdk-app.dac.native","id": "com.libertyglobal.awesome","version": "1.0.0","appName": "Awesome Application",...}}alt[application not active]result{"jsonrpc": "2.0","id": "1223","result": {"handle": "a76a9ad56769634dbbc9c54bac15ddb9"}}[application active (locked by AWC)]error{"code": 1009,"message": "ERROR_APP_ACTIVE"}loop[periodically check progress]getProgress'{"jsonrpc": "2.0","id": "1223","method": "LISA.1.getProgress","params": {"handle": "a76a9ad56769634dbbc9c54bac15ddb9"}}result{"jsonrpc": "2.0","id": "1223","result": {"progress": 75}}StartcheckIfEntryExists(appId)truelock{"method": "LISA.1.lock","params": {"id": "com.libertyglobal.app.awesome","version": "1.0.0"}}"Uninstall in progress"error{"code": 1009,"message": "ERROR_APP_UNINSTALLING"}5 minutes lateroperationStatus{"id": "1223","method": "events.dacbg.lisa.1.operationStatus","params": {"handle": "4c4712a4141d261ec0ca8f9037950685","operation": "Installed","id": "com.libertyglobal.app.awesome","version": "1.0.0","status": "Success","details": "Downloaded 2342 KB, unpacked 3233 KB"}}operationStatus{"id": "62","method": "events.awc.lisa.1.operationStatus","params": {"handle": "4c4712a4141d261ec0ca8f9037950685","operation": "Installed","id": "com.libertyglobal.app.awesome","version": "1.0.0","status": "Success","details": "Downloaded 2342 KB, unpacked 3233 KB"}}getList{"jsonrpc": "2.0","id": "1223","method": "LISA.1.getList","params": {"category": "application"}}result <apps>loop[iterate through getList result]checkIfEntryExists(appId)trueAWC::ApplicationRegistry.addEntry(appId)loop[list of properties]AWC::ApplicationRegistry.setProperty(appId,key,value)finished

AWC Start DAC Application

Main UIAWCLISA ContainerThunderMainUIMainUIApplication ControllerApplication ControllerAppRegistryAppRegistryLISA PluginLISA PluginOCIContainerOCIContainer1Start2checkIfEntryExists(appId)3true4lock{"method": "LISA.1.lock","params": {"id": "com.libertyglobal.app.awesome","version": "1.0.0"}}alt[lock succesfull]5result{"jsonrpc": "2.0","id": "1223","result": {"handle": "a76a9ad56769634dbbc9c54bac15ddb9"}}[application uninstallation in progress]6error{"code": 1009,"message": "ERROR_APP_UNINSTALLING"}7onStateChange(appId,starting)8Parse MIME TypeSelect AppRunner9getStorageDetails(id)10Result11startContainerFromCryptedBundle5 seconds later12onContainerStarted13onStateChange(appId,started)

AWC Stop DAC Application

Main UIAWCLISA ContainerThunderMainUIMainUIApplication ControllerApplication ControllerAppRegistryAppRegistryLISA PluginLISA PluginOCIContainerOCIContainer1Stop2checkIfEntryExists(appId)3true4onStateChange(appId,stopping)5Parse MIME TypeSelect AppRunner6stopContainer5 seconds later7onContainerStopped8unlock9result <ok>10onStateChange(appId,stopped)

  • No labels