Skip to content

Commit

Permalink
Merge branch 'GPII-3193'
Browse files Browse the repository at this point in the history
* GPII-3193: (25 commits)
  GPII-3193: Code clean-up as per code review suggestions.
  GPII-3193: Fixed the test failure on windows.
  GPII-3193: Addressed review comments: improved the production config test to start the test when the kettle server is ready and noUser keyin completes. Also included a couple of other minor improvements.
  GPII-3193: Fixed the production config tests.
  GPII-3193: Fixed the race condition at handling user logon requests.
  GPII-3193: Improved performProximityTriggered() to solve the race situation as per code review suggestion.
  GPII-3193: Improvements as per code review.
  GPII-3193: Removed /getGpiiKey end point and moved/renamed invokePromiseProducer() to the shared testing directory.
  GPII-3193: Got rid of the "isProcessingActionQueue" flag.
  GPII-3193: Got rid of the "isProcessingUserLogonRequestQueue" flag.
  GPII-3193: Added tests for lifecycle manager user logon request.
  GPII-3193: Refactored to use lifecycle manager invokers to handle user login, logout and proximityTriggered requests.
  GPII-3193: Fixed a test failure.
  GPII-3193: Added more tests.
  GPII-3193: Updated documentation.
  GPII-3193: Fixed getGpiiKeyTests.
  GPII-3193: Fixed all other node tests except GetGpiiKeyTests.
  GPII-3193: Fixed a couple of issues with handling user logon requests.
  GPII-3193: Removed the unnecessary dynamic user logon request indexer as well as moving UserLogonStateChange.js from flowManager to lifecycleManager.
  GPII-3193: Added setTimeout() for keying in with noUser when GPII has no active key. This is to work around the issue that the /device kettle request sourced from noUser key-in somehow binds with the previous logout kettle request that has been destroyed and causes failure.
  ...
  • Loading branch information
amb26 committed Sep 5, 2018
2 parents d42b635 + 360f155 commit bddf0f6
Show file tree
Hide file tree
Showing 54 changed files with 2,064 additions and 1,057 deletions.
21 changes: 12 additions & 9 deletions .nycrc
Expand Up @@ -32,15 +32,15 @@
"!**/gpii/node_modules/flowManager/src/BrowserChannel.js",
"!**/gpii/node_modules/flowManager/src/CloudBasedFlowManager.js",
"!**/gpii/node_modules/flowManager/src/FlowManager.js",
"!**/gpii/node_modules/flowManager/src/FlowManagerRequests.js",
"!**/gpii/node_modules/flowManager/src/GetGpiiKey.js",
"!**/gpii/node_modules/flowManager/src/MatchMaking.js",
"!**/gpii/node_modules/flowManager/src/PSPChannel.js",
"!**/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js",
"!**/gpii/node_modules/flowManager/src/UntrustedFlowManager.js",
"!**/gpii/node_modules/flowManager/src/SessionAware.js",
"!**/gpii/node_modules/flowManager/src/SettingsDataSource.js",
"!**/gpii/node_modules/flowManager/src/SettingsGetHandler.js",
"!**/gpii/node_modules/flowManager/src/SettingsPutHandler.js",
"!**/gpii/node_modules/flowManager/src/UserLogonStateChange.js",
"!**/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js",
"!**/gpii/node_modules/flowManager/src/UntrustedFlowManager.js",
"!**/gpii/node_modules/flowManager/src/UserLogonHandlers.js",
"!**/gpii/node_modules/gpii-oauth2/gpii-oauth2-authz-server/index.js",
"!**/gpii/node_modules/gpii-oauth2/gpii-oauth2-authz-server/src/AuthGrantFinder.js",
"!**/gpii/node_modules/gpii-oauth2/gpii-oauth2-authz-server/src/AuthServer.js",
Expand All @@ -63,6 +63,8 @@
"!**/gpii/node_modules/lifecycleManager/src/LifecycleManager.js",
"!**/gpii/node_modules/lifecycleManager/src/LifecycleManagerSession.js",
"!**/gpii/node_modules/lifecycleManager/src/Resolvers.js",
"!**/gpii/node_modules/lifecycleManager/src/UserLogonRequest.js",
"!**/gpii/node_modules/lifecycleManager/src/UserLogonStateChange.js",
"!**/gpii/node_modules/matchMakerFramework/index.js",
"!**/gpii/node_modules/matchMakerFramework/src/MatchMakerFramework.js",
"!**/gpii/node_modules/matchMakerFramework/src/MatchMakerUtilities.js",
Expand Down Expand Up @@ -94,15 +96,16 @@
"!**/gpii/node_modules/userListeners/src/pcsc.js",
"!**/gpii/node_modules/userListeners/src/usb.js",
"!**/gpii/node_modules/testing/index.js",
"!**/gpii/node_modules/testing/src/PouchTestCaseHolder.js",
"!**/gpii/node_modules/testing/src/Acceptance.js",
"!**/gpii/node_modules/testing/src/BrowserIncludes.js",
"!**/gpii/node_modules/testing/src/CloudBased.js",
"!**/gpii/node_modules/testing/src/CloudBasedOAuth2TestsUtils.js",
"!**/gpii/node_modules/testing/src/BrowserIncludes.js",
"!**/gpii/node_modules/testing/src/Integration.js",
"!**/gpii/node_modules/testing/src/Mocks.js",
"!**/gpii/node_modules/testing/src/NockUtils.js",
"!**/gpii/node_modules/testing/src/PouchTestCaseHolder.js",
"!**/gpii/node_modules/testing/src/PromiseUtils.js",
"!**/gpii/node_modules/testing/src/Testing.js",
"!**/gpii/node_modules/testing/src/Mocks.js",
"!**/gpii/node_modules/testing/src/Integration.js",
"testData",
"tests",
"reports",
Expand Down
2 changes: 1 addition & 1 deletion documentation/CloudBasedFlow.md
Expand Up @@ -3,7 +3,7 @@
This page describes the flow when GPII is run in cloud based flowmanager mode. This mainly involves two files:

* `CloudBasedFlowManager.js` - This will be referred to as `Cloud Based FlowManager` in the below
* `FlowManagerRequests.js` - referred to in the below as `FlowManagerRequests`.
* `MatchMaking.js` - referred to in the below as `FlowManagerRequests`.

## Overview and APIs

Expand Down
25 changes: 14 additions & 11 deletions documentation/FlowManager.md
Expand Up @@ -10,24 +10,27 @@ Manager](LifecycleManager.md).

Depending on what the usage of the system is, the flows will be different. For example user login, user log off, and
retrieving settings from the system in "cloud based flowmanager" mode are all different. Each "flow" is managed in a
different file, with the common events, functions, etc., located in `FlowManager.js` and `FlowManagerRequests.js`. The
different file, with the common events, functions, etc., located in `FlowManager.js` and `MatchMaking.js`. The
different kinds of flows are:

* **User Login** (UserLogonStateChange.js) - the flow for a user keying in to the system. The flow is described in
* **User Login** (`UserLogonHandlers.js`) - the flow for a user keying in to the system. The flow is described in
details in the [loginAndLogoutFlow](LoginAndLogoutFlow.md) document
* **User Logout** (UserLogonStateChange.js) - the flow for a user keying out of the system
* **Retrieving Settings** (CloudBasedFlowManager.js) - used to retrieve the settings when the system is running in
* **User Logout** (`UserLogonHandlers.js`) - the flow for a user keying out of the system
* **User Logon State Change** (`UserLogonHandlers.js`) - the flow for changing a user's logon state
* **Retrieve Settings** (`CloudBasedFlowManager.js`) - used to retrieve the settings when the system is running in
cloud-based mode. See [CloudBasedFlow](CloudBasedFlow.md) for more details
* **Get GPII Key** (`GetGpiiKey.js`) - retrieval of the GPII key of the currently logged in user.
* **Update Preferences** (`CloudBasedFlowManager.js`) - used to update the preferences when the system is running in
cloud-based mode. See [CloudBasedFlow](CloudBasedFlow.md) for more details

## Reserved GPII Key "noUser"

## Important events:
The reserved special GPII key "noUser" is keyed into the system when there is not an actual key keyed in. This includes:

There are a few notification events on the flowmanager related to the key-in and key-out process.
* When GPII starts
* Once an actual GPII key is keyed out

* userLoginInitiated: fired when the process of keying in a user (ie. configuring the system) starts,
* userLogoutInitiated: fired when the process of keying out a user (ie. restoring the system) has started,
* userLoginComplete: fired when the process of keying in a user (ie. configuring the system) has completed,
* userLogoutComplete: fired when the process of keying out a user (ie. restoring the system) has completed,
The present of "noUser" key allows users to continue to change settings via QSS (Quick Strip Set) when no actual GPII
key is keyed into the system.

## APIs

Expand Down
109 changes: 93 additions & 16 deletions documentation/LifecycleManager.md
@@ -1,18 +1,76 @@
# lifecycleManager
# Lifecycle Manager

The Lifecycle Manager is responsible for actually configuring the users system via setting handlers and launch handlers.
It is the only component in the system that keeps state. This is done in the "session" member of the lifecycleManager
component, and tracks what changes have been done to the system, what the original configuration of the system was and
which user is currently logged in.
The Lifecycle Manager is responsible for actually performing user login, logout, retrieving the active GPII key
requests. It also configs the users system via setting handlers and launch handlers.

## LifecycleManager Queue
The Lifecycle Manager is the only component in the system that keeps state. This is done in the "session" member of
the Lifecycle Manager component, and tracks what changes have been done to the system, what the original configuration
of the system was and which user is currently logged in.

The lifecycleManager queue is used to hold the high-level action that needs to happen: starting the login process,
starting logout process, starting the update process. Since the steps of these processes are asynchronous, the queue was
implemented to avoid racing issues between these processes (e.g. if a logout attempt is started before login is
complete, etc).
## Lifecycle Manager Model

Each item in the queue should have the following format:
This section lists a few important model items that the Lifecycle Manager keeps track of.

### Current User Logon

The model path `currentUserLogon` holds information about the last actual user logon state for the proximityTriggered
logon request to verify its [debounce rule](FlowManager.md#user-logon-state-change-get-usergpiikeyproximitytriggered).
Note that this model item does not keep track of the logon of "noUser" key.

This model structure has the following format:

```snippet
{
currentUserLogon: {
type: <String>, // "login" or "logout"
gpiiKey: <String>, // A GPII key`
timeStamp: <Number> // Timestamp that the logon occurs
}
}
```

### Logon Change

The model path `logonChange` holds information about the most recent login/logout action including the "noUser" key.

This model structure has the following format:

```snippet
{
logonChange: {
type: <String>, // "login" or "logout"
inProgress: <Boolean> // Whether the handling of the logon change is in progress
gpiiKey: <String>, // A GPII key`
timeStamp: <Number> // Timestamp that the logon occurs
}
}
```

## Lifecycle Manager Maintained Queues

### User Logon Request Queue

The Lifecycle Manager user logon request queue is used to hold all requests for user logging in and logging out.
The queue is handled sequentially to avoid racing issues (e.g. the next request will wait until the previous request
finishes before the processing).

The logging in and logging out items in the queue should have the following format:

```snippet
{
gpiiKey: <String>, // A GPII key
logonState: <String> // "login" or "logout"
}
```

### Action Queue

The Lifecycle Manager action queue is used to hold the high-level action that needs to happen: starting the login process,
starting logout process, starting the update process. Since the steps of these processes are asynchronous, the action
queue was implemented to avoid racing issues between these processes (e.g. if a logout attempt is started before login
is complete, etc).

Each item in the action queue should have the following format:

```snippet
{
Expand All @@ -24,17 +82,36 @@ Each item in the queue should have the following format:

The variable `<unresolvedFunctionToCall>` is an unresolved (i.e. string) single-argument function that returns a
promise. The promise should be resolved when the function is complete (including side-effects). `<arguments>` is the
argument to pass to the function. `<InvokerName>` is the name of the invoker that was called on the lifecycleManager for
triggering the adding of the item to the queue.
argument to pass to the function. `<InvokerName>` is the name of the invoker that was called on the Lifecycle Manager for
triggering the adding of the item to the action queue.

The action queue is run sequentially, and an item is considered "done" once the promise returned by its function is resolved.

## Main Functions of Lifecycle Manager:

### Handle User Logon Requests

The lifecycle manager provides three invokers to handle three type of user logon requests: "login", "logout" and ["proximityTriggered"]((FlowManager.md#user-logon-state-change-get-usergpiikeyproximitytriggered)):

* `performLogin`: Handle login requests
* `performLogout`: Handle logout requests
* `performProximityTriggered`: Handle proximityTriggered requests

These invokers perform checks and add corresponding login and logout requests to the user logon request queue. Each
request in the queue triggers the creation of a dynamic user logon request component that instantiates the corresponding
request handler component:

* `"gpii.lifecycleManager.loginRequest"`: handle login requests
* `"gpii.lifecycleManager.logoutRequest"`: handle logout requests

The queue is run sequentially, and an item is considered "done" once the promise returned by its function is resolved.
The dynamic request component will be automatically destroyed once the handling of the request completes.

## Main functions of lifecycle manager:
### Start, Stop and Update Processes

The lifecycle manager has three invokers that are generally the ones that will be called from the general system, namely
"start", "stop" and "update". These invokers are manually created, so are not obvious to spot on the component defaults
block, but they are the ones to be used (instead of the processStart, processStop and processUpdate). They will add the
relevant task to the Lifecycle Managers queue:
relevant task to the Lifecycle Managers action queue:

* `start`: Should be called when keying in (configuring the system)
* `stop`: Should be called when keying out (restoring the system)
Expand Down
28 changes: 13 additions & 15 deletions documentation/LoginAndLogoutFlow.md
Expand Up @@ -40,19 +40,24 @@ inserting/removing the USB, respectively

## Technical description

The core part of the flow is defined in two files:
The core part of the flow is defined in these files:

* `UserLogonStateChange.js` contains the handling of the logon related endpoints kicks off the related process. It
contains individual handlers for the `login`, `logout` and `proximityTriggered` URLs. These handlers all have the
`gpii.flowManager.userLogonHandling.stateChangeHandler` grade, which is the component that contains the functionality
for the actual logging in and logging off.
* `FlowManagerRequests.js` which describes the remaining part of the flow (e.g. fetching resources, matchmaking, etc.).
* `UserLogonHandlers.js` contains the handling of the logon related endpoints kicks off the related process. It
contains individual handlers for the `login`, `logout` and `proximityTriggered` URLs. These handlers add user logon
request to Lifecycle Manager user logon request queue. Lifecycle Manager then processes the queue in sequence to
perform actual logging in, loggin out and retrieving the current logged in GPII key.
* `UserLogonStateChange.js` contains the functionality for the actual logging in, logging out and retrieving the active
GPII key.
* `MatchMaking.js` describes the remaining part of the flow (e.g. fetching resources and preferences, matchmaking,
etc.).

The user login process is as follows:

1. a GET request is sent to either `/user/:gpiiKey/login` or `/user/:gpiiKey/proximityTriggered`. This is retrieved by
the relevant handler in `UserLogonStateChange`, and if it is found that the GPII key needs to be logged in, the
`onGpiiKey` event is fired (via the `gpii.flowManager.userLogonHandling.loginUser` function)
the relevant handler in `UserLogonHandlers`. The handler adds a relevant login or logout request to Lifecycle
Manager user logon request queue, which trigger the actual logging in or logging out. If it is found that the GPII
key needs to be logged in, the `onGpiiKey` event is fired (via the
`gpii.lifecycleManager.userLogonHandling.loginUser` function)
2. the `onGpiiKey` event has three listeners:
1. UserLogonStateChange's `getDeviceContext`, which fetches the device reporter data. When this has been fetched an
`onDeviceContext` event is fired.
Expand All @@ -77,10 +82,3 @@ The user login process is as follows:
match maker frameworks internal workings, see: [Match Maker Framework Documentation](MatchMakerFramework.md)
6. `onMatchDone` is being listened to by the `startLifecycle` (UserLogonStateChange), which applies the settings to the
system via the functionality in the LifecycleManager.

## Finally, there are some important events exposed on the `flowManager` component:

* userLoginInitiated: fired when the process of keying in a user (ie. configuring the system) starts.
* userLogoutInitiated: fired when the process of keying out a user (ie. restoring the system) has started.
* userLoginComplete: fired when the process of keying in a user (ie. configuring the system) has completed.
* userLogoutComplete: fired when the process of keying out a user (ie. restoring the system) has completed.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gpii/node_modules/contextManager/src/ContextManager.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gpii/node_modules/deviceReporter/src/DeviceReporter.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion gpii/node_modules/flowManager/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit bddf0f6

Please sign in to comment.