@c  This document is part of the Liza Data Collection Framework manual.
@c  Copyright (C) 2017 R-T Specialty, LLC.
@c
@c    Permission is granted to copy, distribute and/or modify this document
@c    under the terms of the GNU Free Documentation License, Version 1.3
@c    or any later version published by the Free Software Foundation;
@c    with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
@c    Texts.  A copy of the license is included in the section entitled ``GNU
@c    Free Documentation License''.

@node Server
@chapter Liza Server
@maintenance{The @srcrefjs{server/daemon,Daemon} monolith and
               @srcrefjs{server,Server},
                 among other things,
                 need refactoring.}

@helpwanted{}

@cindex Server
The @dfn{server}@footnote{
    @cindex Quote Server
    Which may also be referenced as ``quote server'' in certain legacy
      contexts,
        referring to Liza's origin as an insurance rating system.}
  is a RESTful service that serves as the HTTP server.
It is designed to run under Node.js,
  motivated by the benefits of sharing code with the@tie{}Client
  (@pxref{Client}).
The daemon is handled by the abstract @srcrefjs{server/daemon,Daemon}
  monolith,
    which requires that a concrete @code{#getEncryptionService}
    method be defined by a subtype or trait.
An example script to start the server is shown in @ref{f:server-start}.

@cindex Encryption Service
@tip{For local development,
       or to avoid use of any encryption service,
       use @srcrefjs{server/daemon,DevDaemon},
       which uses a dummy encryption service.}

To start the server,
  invoke @srcrefraw{bin/server}.
You may also invoke @srcrefraw{bin/server.js} directly using Node.js,
  but the use of @srcref{bin/server} is recommended,
    as it uses the Node.js executable determined at configure-time,
    along with any command-line options required for Liza@tie{}Server
      to function correctly.
Additional options can be provided to Node.js using the
  @var{NODE_FLAGS} environment variable,
    which will be @emph{appended} to the configure-time flags.
This environment variable is @emph{not} escaped or quoted,
  so be mindful of word expansion.

@float Figure, f:server-start
@example
  $ bin/server -c path/to/config.json

  # providing additional options to node
  $ NODE_FLAGS=--debug bin/server -c path/to/config.json
@end example
@caption{Starting the Liza Server}
@end float



@cindex HTTP Server
The HTTP server is managed by
  @srcrefjs{server/daemon,http_server}.


@menu
* Configuration:Server Configuration. Server configuration.
* Requests::                          Handling HTTP requests.
* Posting Data::                      Handling step saves and other posts.
* Server-Side Data API Calls::        Accessing external resources on the server.
* Encryption Service::                Managing sensitive data.
@end menu



@node Server Configuration
@section Configuration
@helpwanted{}

@cindex Configuration
Liza is migrating to actual configuration file in place of environment
  variables.
If no configuration is explicitly specified,
  it uses @srcrefraw{conf/vanilla-server.json}.

Configuration loading is handled by @srcrefjs{conf,ConfLoader}.
The configuration store @srcrefjs{conf,ConfStore} is asyncrhonous,
  so loading configuration from any external system is supported.@footnote{
    Provided that you write the code to load from that system,
      that is.}


@node Requests
@section HTTP Requests
@helpwanted{}

@cindex Session
@cindex PHPSESSID
@cindex Memcache
Each HTTP request produces a @srcrefjs{server/request,UserRequest}
  associated with a @srcrefjs{server/request,UserSession}.
Sessions are tightly coupled with PHP@footnote{
    They don't have to be@mdash{}refactoring is needed.};
  an existing PHP session is expected,
    as identified by the @samp{PHPSESSID} cookie.
Sessions are shared via Memcache
  (see @srcrefjs{server/cache,ResilientMemcache}).@footnote{
    Via a @url{https://secure.php.net/manual/en/memcached.sessions.php,memcache session handler}.}
 If a session is not found (or is invalid),
   an HTTP@tie{}@code{500} status code is returned and the
   HTTP@tie{}request is aborted.

@cindex Timeout
@cindex Request timeout
Requests are subject to a 120@tie{}second timeout,
  after which the request will be served an HTTP@tie{}@code{408}
  status code.
Note that this @emph{does not stop background processing}@mdash{
  }this timeout exists to prevent the user from hanging indefinitely.

@cindex Long-running requests
@tip{If a process intends to perform background processing for any length
       of time (longer than a few seconds),
         it should complete the request as quickly as possible and
         use some other mechanism to report back progress
         (e.g. polling).}

The @srcrefjs{server/request,UserRequest} exposes raw request data with
  minor processing.

@table @strong
  @item Path (@jsmethod{getUri})
  The path component of the URI.  The method name is unfortunate.

  @item Query data (@jsmethod{getGetData})
  Query string processed into a key/value object.
  Despite the name,
    this is also populated if non-GET requests contain query strings.

  @item POST data (@jsmethod{getPostData})
  POST data processed into an object as if it were a query string
    (just as @jsmethod{getGetData}).
  Since this requires data that is streamed asynchronously,
    this method takes a callback that waits for all data to become
    available;
      if the data are already available,
        it is immediately invoked with the processed POST data.

  @item Cookies (@jsmethod{getCookies})
  Cookies parsed into a key/value object.

  @item Remote address (@jsmethod{getRemoteAddr})
  IP address of the origin of the request.
  If the server is behind a proxy that sets the
    @samp{X-Forwarded-For} header,
      it is used instead.

  @item Host address (@jsmethod{getHostAddr})
  Hostname of the server.
  If the server is behind a proxy that sets the
    @samp{X-Forwarded-Host} header,
      it is used instead.

  @item Origin (@jsmethod{getOrigin})
  Origin of request.
  Only available if at lease one of the @samp{Origin} or
    @samp{Referer} headers are set.
  This is useful mainly for determining the protocol and host while
    behind a proxy.

  @item User agent (@jsmethod{getUserAgent})
  The user agent string of the request.

  @item Session ID (@jsmethod{getSessionId})
  The user's unique session id (@samp{PHPSESSID}).

  @item Session ID name (@jsmethod{getSessionIdName})
  The name of the cookie from which the session ID originated
    (hard-coded to @samp{PHPSESSID}).
@end table

@todo{Document return format and writing response data.}



@node Posting Data
@section Posting Data
@cindex Post
@cindex Bucket diff
@cindex Step save
A diff of the bucket data (@pxref{Bucket Diff}) is posted to the
  server on step@tie{}save.
This operation is performed asynchronously@mdash{
  }the client need not wait for the step to save before the next can
  be requested.

Since validations are shared between the server and the client
  (@pxref{Validation}),
    saving should only fail in exception situations.
Should a failure occur,
  the server will instruct the client to kick the user back to the
  previous step (@dfn{kickback}).

A step cannot be saved if it is locked;
  such attempts will result in an error.

To prevent a user from skipping steps,
  the client may post only one step past the last step that has
  successfully saved;
    otherwise, the user is kicked back to the last step that was saved.

Once those basic checks have passed,
  the document is updated:

@enumerate
  @item
  @cindex Data sanitization
  The diff is first @dfn{sanitized} to strip out unknown fields,
    internal fields posted by non-internal users,
    and to filter fields on permitted characters;

  @item
  The sanitized diff is then applied to the existing bucket on the
    document;

  @item
  @cindex Calculated values, server-side
  Calculated values marked for storage (@pxref{Calculated Values}) are
    re-calculated on the server (the values posted by the client have
    already been discarded by the first step in this list);

  @item
  Server-side @dapi{} calls (@pxref{Data API}) are triggered using the
    diff as input data and an empty bucket for response storage
    (@pxref{Server-Side Data API Calls});

  @item
  @cindex Premium calculation date
  The last premium calculation date is cleared (indicating that
    premiums are no longer valid);@footnote{
      This concept is tightly coupled with insurance;
        it should be factored out at some point.}

  @item
  @cindex Encryption
  Data marked as sensitive is encrypted and the ciphertext written to
    the bucket in place of the plaintext (@pxref{Encryption Service});

  @item
  @cindex Top visited step
  The current step is incremented and the @dfn{top visited
    step}@tie{} is set to the larger of the incremented step or the
    existing top visited step id; and then

  @item
  The new document state and bucket data are written to the database.
@end enumerate



@node Server-Side Data API Calls
@section Server-Side Data API Calls
@maintenance{This makes use of @srcrefjs{server/meta,DapiMetaSource}
               to encapsulate the horrible API of @srcrefjs{dapi,DataApiManager};
                 the latter needs cleanup to remove the former.}

@cindex Data API
@cindex Document metadata
Server-side @dapi{} calls (@pxref{Data API}) are triggered on
  step save (@pxref{Posting Data}) and are handled much like they are
  on the client.
Such calls are made automatically only for document metadata.
Results of sever-side calls are @emph{not} written to the bucket
  and are therefore useful for data that the client should not be
  permitted to modify;
    it also allows data to be kept secret from the client.@footnote{
      All bucket data is served to the client,
        with the exception of internal fields if the user is non-internal.}

@dapi{} results on the client can be mapped back to multiple bucket values;
  the server, however, has serious concerns with how data are
  propagated for data integrity and security reasons.
Further,
  document metadata can be structured,
  unlike the Bucket which has a rigid matrix format (@pxref{Bucket}).
Therefore,
  the entire response is mapped into the parent field;
    defined return values are used only for filtering.

When a DataAPI request is made,
  it supercedes any previous requests that may still be pending for
    that same index.


@node Encryption Service
@section Encryption Service
@helpwanted
