openmct/platform/policy
Andrew Henry 433dee0314 Update test specs to use Jasmine 3 (#2089)
* Updated Karma and Jasmine versions

* Added DOMObserver class. Supports promise-based testing of DOM changes

Update asynchronous test specs to use promises or done() instead of waitsFor/runs

* Modified ActionCapability to duplicate context object properties as own properties for better object equality comparisons

* Global find + replace to fix syntax issues

* Fixed various issues caused by non-deterministic runtime order of tests in Jasmine 3. Fixed issues caused by changes to determination of object equality

* Addressed review comments

* Resolved merge conflicts with master

* Fixed style errors

* Use spy.calls.count() instead of manually tracking
2018-06-29 17:32:59 -07:00
..
src [Copyright] Update copyright year across platform code references 2018-05-14 15:46:17 -07:00
test Update test specs to use Jasmine 3 (#2089) 2018-06-29 17:32:59 -07:00
bundle.js [Copyright] Update copyright year across platform code references 2018-05-14 15:46:17 -07:00
README.md [Licenses] Update copyright year to 2017 2017-04-05 14:52:46 -07:00

Overview

This bundle provides support for policy in Open MCT. Policy can be used to limit the applicability of certain actions, or more broadly, to provide an extension point for arbitrary decisions.

Services

This bundle introduces the policyService, which may be consulted for various decisions which are intended to be open for extension.

The policyService has a single method, allow, which takes three arguments and returns a boolean value (true if policy says this decision should be allowed, false if not):

  • category: A string identifying which kind of decision is being made. Typically, this will be a non-plural form of an extension type that is being filtered down; for instance, to check whether or not a given action should be returned by an actionService, one would use the action category of extension.
  • candidate: An object representing the thing which shall or shall not be allowed. Usually, this will be an instance of an extension of the category defined above.
    • This does need to be the case; additional policies which are not specific to any extension may also be defined and consulted using unique category identifiers. In this case, the type of the object delivered for the candidate may be unique to the policy type.
  • context: An object representing the context in which the decision is occurring. Its contents are specific to each policy category.
  • callback: Optional; a function to call if the policy decision is rejected. This function will be called with the message string (which may be undefined) of whichever individual policy caused the operation to fail.

Design rationale: Returning a boolean here limits the amount of information that can be conveyed by a policy decision, but has the benefit of simplicity. In MCT on the desktop, the policy service returned a more complex object with both a boolean status and a string message; the string message was used rarely (by only around 15% of policy user code) and as such is made optional in the call itself here.

Design rationale: Returning a boolean instead of a promise here implies that policy decisions must occur synchronously. This limits the logic which can be involved in a policy decision, but broadens its applicability; policy is meant to be used by a variety of other services to separate out a certain category of business logic, and a synchronous response means that this capability may be utilized by both synchronous and asynchronous services. Additionally, policies will often be used in loops (e.g. to filter down a set of applicable actions) where latency will have the result of harming the user experience (e.g. the user right-clicks and gets stuck waiting for a bunch of policy decisions to complete before a menu showing available actions can appear.)

The policyService is a composite service; it may be modified by adding decorators, aggregators, etc.

Service Components

The policy service is most often used by decorators for other composite services. For instance, this bundle contains a decorator for actionService which filters down the applicable actions exposed by that service based on policy.

Policy Categories

This bundle introduces action as a policy category. Policies of this category shall take action instances as their candidate argument, and action contexts as their context argument.

Extensions

This bundle introduces the policies category of extension. An extension of this category should have both an implementation, as well as the following metadata:

  • category: A string identifying which kind of policy decision this effects.
  • message: Optional; a human-readable string describing the policy decision when it fails.

An extension of this category must also have an implementation which takes no arguments to its constructor and provides a single method, allow, which takes two arguments, candidate and context (see descriptions above under documentation for actionService) and returns a boolean indicating whether or not it allows the policy decision.

Policy decisions require consensus among all policies; that is, if a single policy returns false, then the policy decision as a whole returns false. As a consequence, policies should be written in a permissive manner; that is, they should be designed to prohibit behavior under a specific set of conditions (by returning false), and allow any behavior which does not match those conditions (by returning true.)