Application Configuration Overview

Overview

The generated application code can be run unchanged for testing purposes, but some external setup is required.

  1. Edit the generated .prd.config.json file to define your production configuration.
  2. Edit the generated .dev.config.json file to define your development / testing configuration.
  3. When using SSL to test locally, SSL certs will be needed. See the SSL setup section below for instructions regarding the generation of certificates suitable for local testing via go test.

Configuration File Overview

Sample Development Configuration File


    {
        "external_address": "127.0.0.1:3000",
        "internal_address": "127.0.0.1:4444",
        "env": "dev",
        "ping_cycle": 1,
        "failure_threshold": 5,
        "pepper": "secret-pepper-key",
        "hmac_Key": "secret-hmac-key",
        "database": {
            "db_dialect": "postgres",
            "host": "localhost",
            "port": 5432,
            "usr": "godev",
            "password": "gogogo123",
            "name": "glrestgen",
            "ormLogActive": true,
            "ormDebugTraceActive": false
        },
        "group_leader_kvs": {
            "local_standalone": {
                "active": true,
                "internal_address": "127.0.0.1:4444"
            },
            "redis": {
                "active": false,
                "max_idle": 80,
                "max_active": 12000,
                "redis_protocol": "tcp",
                "redis_address": "127.0.0.1:6379"
            },
            "memcached": {
                "active": false,
                "memcached_addresses": [
                    "192.168.112.50:11211"
                ]
            },
            "sluggo": {
                "active": false,
                "sluggo_address": "127.0.0.1:7070"
            }
        },
        "logging": {
            "active": true,
            "callLocation": true,
            "colorMsgTypes": true,
            "infoMsgs": false,
            "warningMsgs": false,
            "errorMsgs": true,
            "debugMsgs": false,
            "traceMsgs": false
        },
        "cert_file": "",
        "key_file": "",
        "rsa256_priv_key_file": "",
        "rsa256_pub_key_file": "",
        "rsa384_priv_key_file": "",
        "rsa384_pub_key_file": "",
        "rsa512_priv_key_file": "",
        "rsa512_pub_key_file": "",
        "ecdsa256_priv_key_file": "",
        "ecdsa256_pub_key_file": "",
        "ecdsa384_priv_key_file": "jwtkeys/ecdsa384/ec384.priv.pem",
        "ecdsa384_pub_key_file": "jwtkeys/ecdsa384/ec384.pub.pem",
        "ecdsa521_priv_key_file": "",
        "ecdsa521_pub_key_file": "",
        "jwt_sign_method": "ES384",
        "jwt_lifetime": 120,
        "service_activations": [
            {
                "service_name":   "Person",
                "service_active": true
            },
            {
                "service_name": "Car",
                "service_active": true
            }
        ]
    }


Configuration File Fields

Field Name Optional Description
“external_address” mandatory ‘external_address’ is used to instruct the service instance which tcp address:port to publish the service end-points on.

Example: “external_address”: “192.168.1.66:8080”

“internal_address” mandatory ‘internal_address’ is used to instruct the service instance which address:port to use when accepting inter-group-member web-sockets requests. This address:port should ideally be hosted on a separate interface, as the web-sockets communication is conducted without authentication or encryption.

Example: “internal_address”: “192.168.1.66:4444”

“env” mandatory ‘env’ is used to inform the generated server which mode to run in. The material difference between “dev”, “def” and “prod” is slight; the “dev” and “def” modes run the ORM in debugging mode, thereby causing the generated SQL statements to be written as a log to stdout.

Valid values: “dev” or “def” or “prod”

Example: “env”: “dev”

“ping_cycle” mandatory ‘ping_cycle’ is used to determine the frequency with which the group-members execute a round of pinging. The value must be a whole number > 0. See the Group Membership section of this file for details regarding the execution of a ping-cycle.

Example: “ping_cycle”: 1

“failure_threshold” mandatory ‘failure_threshold’ is used to set the limit for recorded ping failures against any process in the group. At the moment this number is used verbatim, but in the future the number of ping failures required to move a process-status from SUSPECT to FAILED will be dependent on the number of processes in the group. See the Group Membership section of this file for greater detail regarding the ALIVE -> SUSPECT -> FAILED chain of process statuses.

Example: “failure_threshold”: 5

“pepper” mandatory ‘pepper’ is used as a pepper seed to the bcrypt password hash. The generated server handles user login authentication via bcrypt hashing of the password the user entered, then comparing the resulting hash to the stored bcrypt password hash that was created when the user set their initial password. Passwords are not kept anywhere in the system.

Example:“pepper”: “secret-pepper-key”

“hmac_key” N/A ‘hmac_key’ is a legacy configuration option left over from the old CSRF implementation. This field has been deprecated.

Example: “hmac_key”: “some_easily_shoulder_surfable_value”

“database” mandatory is a JSON block holding the access information for the database system. Fill in what is needed for the type of database you are connecting to. SQLite for example, does not have any user-access control etc.
“db_dialect” mandatory ‘dialect’ belongs to the ‘database’ structure and refers to the database dialect to use to connect to the backend DBMS.

Example: “db_dialect”: “postgres”

The following values are permitted: {“postgres”, “mssql”, “hdb”, “sqlite3”, “mysql”}

“host” mandatory ‘host’ belongs to the ‘database’ structure and refers to the ip-address or canonical name of the system hosting the database.

Example: “host”: “localhost”

“port” mandatory ‘port’ belongs to the ‘database’ structure and refers to the port that the database accepts client connections with.

Example: “port”: 5432

“user” mandatory ‘user’ belongs to the ‘database’ structure and refers to the username used by the application to login to the database.

Example: “user”: “godev”

“password” mandatory ‘password’ belongs to the ‘database’ structure and refers to the password required for the application to login to the database.

Example: “password”: “gogogo123”

“name” mandatory ‘name’ belongs to the ‘database’ structure and refers to the name of the database that the application client should connect to.

Example: “name”: “testdb”

“ormLogActive” mandatory ‘ormLogActive’ belongs to the ‘database’ structure and is used to activate log output from the sqac ORM.

Example: “ormLogActive”: false

“group_leader_kvs” mandatory ‘group_leader_kvs’ is a configuration block used to declare the active group-leadership KVS details.
“local_standalone” mandatory ‘local_standalone’ belongs to the ‘group_leader_kvs’ structure and contains a configuration block that can be used to instruct the jiffy application instance to run the group-membership KVS lookup in standalone mode. This is the default mode for a generated jiffy application.
“local_standalone -> “active” mandatory ‘local_standalone -> active’ belongs to the ‘group_leader_kvs’ structure and holds a boolean value (true/false) indicating whether or not the jiffy application is running the group-membership KVS lookup in standalone mode.
“local_standalone -> internal_address” conditional ‘local_standalone -> internal_address’ holds the address:port of the standalone jiffy application server. The address:port provided here should be locally ping-able.
“redis” mandatory ‘redis’ belongs to the ‘group_leader_kvs’ structure and contains a configuration block that can be used to instruct the jiffy application instance to access a redis system when performing group-leadership KVS reads and updates.
“redis -> active” mandatory ‘redis -> active’ belongs to the ‘group_leader_kvs’ structure and holds a boolean value (true/false) indicating whether or not the jiffy application is accessing a redis system to perform group-leadership KVS reads and updates.
“redis -> “max_idle” mandatory ‘redis -> max_idle’ belongs to the ‘group_leader_kvs’ structure and holds a uint value specifying a maximum number of idle redis client connections can remain active at any point in time.
“redis -> max_active” mandatory ‘redis -> max_active’ belongs to the ‘group_leader_kvs’ structure and holds a uint value specifying a maximum number of active redis client connections a jiffy application instance is permitted to hold at any point in time.
“redis -> max_protocol” mandatory ‘redis -> max_protocol’ belongs to the ‘group_leader_kvs’ structure and holds a string value specifying which transport should be used to communicate with the redis group-leadership KVS system. tcp is the default value.
“redis -> max_address” mandatory ‘redis -> max_address’ belongs to the ‘group_leader_kvs’ structure and holds a string value specifying the address:port at which the redis group-leadership KVS can be accessed.
“memcached” mandatory ‘memcached’ belongs to the ‘group_leader_kvs’ structure and contains a configuration block that can be used to instruct the jiffy application instance to access a memcached system/cluster when performing group-leadership KVS reads and updates.
“memcached -> active” mandatory ‘memcached -> active’ belongs to the ‘group_leader_kvs’ structure and holds a boolean value (true/false) indicating whether or not the jiffy application is accessing a memcached system/cluster to perform group-leadership KVS reads and updates.
“memcached -> addresses” mandatory ‘memcached -> addresses’ belongs to the ‘group_leader_kvs’ structure and holds a json array of string values specifying the address:port(s) at which the memcached group-leadership KVS cluster can be accessed.
“logging” mandatory is a JSON block holding the application logging configuration.
“active” mandatory ‘active’ is a flag that generally activates or deactivates the application logging. When set to false, application logging is deactivated and only Console-type messages will be displayed. When set to true, logs for each activated logging-type (Info, Warning, Error etc.) will be output.
“callLocation” mandatory Setting the ‘callLocation’ flag to true instructs the logging package to append the source-file name and line-location of the previous statement to the log output for all logging-types.
“colorMsgTypes” mandatory Setting the ‘colorMsgTypes’ flag to true instructs the logging package to color the message-type (INFO:, WARNING:, ERROR:, etc.) in the log output. In general log entries observe the following format: <MESSAGE_TYPE:><LOCAL_DATETIME><MESSAGE_TEXT><SOURCE_FILE><SOURCE_LINE_NUMBER>
“infoMsgs” mandatory When set to true, the application will write informational messages to stdout. This is verbose. Defaulted to false.
“warningMsgs” mandatory When set to true, the application will write warning messages to stdout. Defaulted to true.
“errorMsgs” mandatory When set to true, the application will write error messages to stdout. Defaulted to true.
“debugMsgs” mandatory When set to true, the application will write debugging messages to stdout. Defaulted to false.
“traceMsgs” mandatory When set to true, the application will write error messages to stdout. Defaulted to false.
“cert_file” optional ‘cert_file’ should point to the location of a self-signed or purchased certificate file and is used to support https. Maintaining a ‘cert_file’ and ‘key_file’ in the configuration informs the generated server to publish via https.

Example: “cert_file”: “myCert.cer”

“key_file” optional ‘key_file’ should point to the location of the key-file for the self-signed or purchased certificate file referenced in the ‘key_file’ configuration key. Maintaining a ‘cert_file’ and ‘key_file’ in the configuration informs the generated server to publish via https.

Example: “key_file”: “myKeyFile.key”

“rsa256_priv_key_file” optional Private key file for rsa256 JWT verification.

Application access is handled via claims embedded in JWT tokens. The JWT header and payload contain the claims and are encoded as base64. In order to ensure the JWT content has not been tampered with, a verification signature based on the JWT content and a set of public-private keys is included in the JWT. Jiffy generates a set of public-private keys for each supported signing algorithm, but only populates the key configuration files with the set corresponding the value set in the ‘jwt_sign_method’.

Look in the /jwtkeys folder to see the public-private keys generated by Jiffy.

If you have an external system that signs JWT’s with RSA256, it is possible to provide the Jiffy-generated application with the public-private key-pair by setting their locations and names in the ‘rsa256_priv_key_file’ and ‘rsa256_pub_key_file’. This would allow the external authentication system to create access tokens for the Jiffy-generated application, provided that the correct claims were embedded in the JWT header and payload. This effectively enables a very simple single-sign-on facsimile.

The following pub/priv keys can be used for this purpose.

“rsa256_pub_key_file” optional Public key file for rsa256 JWT verification.
“rsa384_priv_key_file” optional Private key file for rsa384 JWT verification.
“rsa384_pub_key_file” optional Public key file for rsa384 JWT verification.
“rsa512_priv_key_file” optional Private key file for rsa512 JWT verification.
“rsa512_pub_key_file” optional Public key file for rsa512 JWT verification.
“ecdsa256_priv_key_file” optional Private key file for ecdsa256 JWT verification.
“ecdsa256_pub_key_file” optional Public key file for ecdsa256 JWT verification.
“ecdsa384_priv_key_file” optional Private key file for ecdsa384 JWT verification.
“ecdsa384_pub_key_file” optional Public key file for ecdsa384 JWT verification.
“ecdsa521_priv_key_file” optional Private key file for ecdsa521 JWT verification.
“ecdsa521_pub_key_file” optional Public key file for ecdsa521 JWT verification.
“jwt_sign_method” mandatory ‘jwt_sign_method’ informs the application which algorithm should be used to sign the JWT created during the login process. In this example, the ecdsa384_pub_key_file & ecdsa384_priv_key_file key files will be used to sign the JWT. Note that this only applies to JWTs that are created via a direct login into the application via the https://appurl:port/login end-point. It is possible that a user will access the application using a JWT generated somewhere with a set of keys that are also known to the application.

Example: “jwt_sign_method”: “ES384”

“jwt_lifetime” mandatory ‘jwt_lifetime’ informs the application how long generated JWT’s are valid for in minutes. The ‘jwt_lifetime’ value is used to determine the value of the JWT’s ‘exp’ claim.

Example:“jwt_lifetime”: 120

“service_activations” mandatory When an application is generated based on the model file(s), all service aspects of the complete set of entities will be created. There may be scenarios where it is appropriate to limit the set of activated services on a running instance of an application server. This can be achieved by maintaining the activation status of each modeled entity in the service_activations list.

‘service_activations is an array containing sets of ‘service_name and ‘service_activation’.

“service_name” mandatory Service name is simply the entity name in CamelCase matching that of the entity’s definition in its respective model file.
“service_activation” mandatory A boolean value (true\false) describing whether the entity’s services are active on the application server. Care must be taken with service activations, as relationships between entities must be considered. Disabling an entity that has a ‘belongsTo’ relation with an active entity can lead to problems. In such a case, the expectation is that another instance of the application server is running with the required services active. While the generated application server does not handle the rerouting or request forwarding in such a case, it should be possible to direct requests to the correct server based on NGinx config (for example).

Database Dialects and Sample Database Configurations

Currently, the following db_dialects are supported by the sqac ORM runtime:

Database JSON Value for db_dialect field
Postgres “db_dialect”: “postgres”
MSSQL (2008+) “db_dialect”: “mssql”
SAP Hana “db_dialect”: “hdb”
SQLite3 “db_dialect”: “sqlite3”
MySQL / MariaDB “db_dialect”: “mysql”

SAP Hana

{
    "external_address": "127.0.0.1:3000",
    "internal_address": "127.0.0.1:4444",
    "env": "dev",
    "ping_cycle": 1,
    "failure_threshold": 5,
    "pepper": "secret-pepper-key",
    "hmac_Key": "secret-hmac-key",
    "database": {
        "db_dialect": "hdb",
        "host": "clkhana01.lab.clockwork.ca",
        "port": 30047,
        "usr": "godev",
        "password": "gogogo123",
        "name": ""
    },
    "cert_file": "",
    "key_file": "",
    "rsa256_priv_key_file": "",
    "rsa256_pub_key_file": "",
    "rsa384_priv_key_file": "",
    "rsa384_pub_key_file": "",
    "rsa512_priv_key_file": "",
    "rsa512_pub_key_file": "",
    "ecdsa256_priv_key_file": "",
    "ecdsa256_pub_key_file": "",
    "ecdsa384_priv_key_file": "jwtkeys/ecdsa384/ec384.priv.pem",
    "ecdsa384_pub_key_file": "jwtkeys/ecdsa384/ec384.pub.pem",
    "ecdsa521_priv_key_file": "",
    "ecdsa521_pub_key_file": "",
    "jwt_sign_method": "ES384",
    "jwt_lifetime": 120,
    "service_activations": [
        {
            "service_name": "Library",
            "service_active": true
        },
        {
            "service_name": "Book",
            "service_active": true
        }
    ]
}

MSSQL
{
    "external_address": "127.0.0.1:3000",
    "internal_address": "127.0.0.1:4444",
    "env": "dev",
    "ping_cycle": 1,
    "failure_threshold": 5,
    "pepper": "secret-pepper-key",
    "hmac_Key": "secret-hmac-key",
    "database": {
        "db_dialect": "mssql",
        "host": "127.0.0.1",
        "port": 1401,
        "usr": "SA",
        "password": "gogogo123",
        "name": "sqactst"
    },
    "cert_file": "",
    "key_file": "",
    "rsa256_priv_key_file": "",
    "rsa256_pub_key_file": "",
    "rsa384_priv_key_file": "",
    "rsa384_pub_key_file": "",
    "rsa512_priv_key_file": "",
    "rsa512_pub_key_file": "",
    "ecdsa256_priv_key_file": "",
    "ecdsa256_pub_key_file": "",
    "ecdsa384_priv_key_file": "jwtkeys/ecdsa384/ec384.priv.pem",
    "ecdsa384_pub_key_file": "jwtkeys/ecdsa384/ec384.pub.pem",
    "ecdsa521_priv_key_file": "",
    "ecdsa521_pub_key_file": "",
    "jwt_sign_method": "ES384",
    "jwt_lifetime": 120,
    "service_activations": [
        {
            "service_name": "Library",
            "service_active": true
        },
        {
            "service_name": "Book",
            "service_active": true
        }
    ]
}

MySQL / MariaDB
{
    "external_address": "127.0.0.1:3000",
    "internal_address": "127.0.0.1:4444",
    "env": "dev",
    "ping_cycle": 1,
    "failure_threshold": 5,
    "pepper": "secret-pepper-key",
    "hmac_Key": "secret-hmac-key",
    "database": {
        "db_dialect": "mysql",
        "host": "192.168.1.50",
        "port": 3306,
        "usr": "godev",
        "password": "gogogo123",
        "name": "sqactst"
    },
    "cert_file": "",
    "key_file": "",
    "rsa256_priv_key_file": "",
    "rsa256_pub_key_file": "",
    "rsa384_priv_key_file": "",
    "rsa384_pub_key_file": "",
    "rsa512_priv_key_file": "",
    "rsa512_pub_key_file": "",
    "ecdsa256_priv_key_file": "",
    "ecdsa256_pub_key_file": "",
    "ecdsa384_priv_key_file": "jwtkeys/ecdsa384/ec384.priv.pem",
    "ecdsa384_pub_key_file": "jwtkeys/ecdsa384/ec384.pub.pem",
    "ecdsa521_priv_key_file": "",
    "ecdsa521_pub_key_file": "",
    "jwt_sign_method": "ES384",
    "jwt_lifetime": 120,
    "service_activations": [
        {
            "service_name": "Library",
            "service_active": true
        },
        {
            "service_name": "Book",
            "service_active": true
        }
    ]
}

PostgreSQL
{
    "external_address": "127.0.0.1:3000",
    "internal_address": "127.0.0.1:4444",
    "env": "dev",
    "ping_cycle": 1,
    "failure_threshold": 5,
    "pepper": "secret-pepper-key",
    "hmac_Key": "secret-hmac-key",
    "database": {
        "db_dialect": "postgres",
        "host": "127.0.0.1",
        "port": 5432,
        "usr": "godev",
        "password": "gogogo123",
        "name": "sqactst"
    },
    "cert_file": "",
    "key_file": "",
    "rsa256_priv_key_file": "",
    "rsa256_pub_key_file": "",
    "rsa384_priv_key_file": "",
    "rsa384_pub_key_file": "",
    "rsa512_priv_key_file": "",
    "rsa512_pub_key_file": "",
    "ecdsa256_priv_key_file": "",
    "ecdsa256_pub_key_file": "",
    "ecdsa384_priv_key_file": "jwtkeys/ecdsa384/ec384.priv.pem",
    "ecdsa384_pub_key_file": "jwtkeys/ecdsa384/ec384.pub.pem",
    "ecdsa521_priv_key_file": "",
    "ecdsa521_pub_key_file": "",
    "jwt_sign_method": "ES384",
    "jwt_lifetime": 120,
    "service_activations": [
        {
            "service_name": "Library",
            "service_active": true
        },
        {
            "service_name": "Book",
            "service_active": true
        }
    ]
}

SQLite
{
    "external_address": "127.0.0.1:3000",
    "internal_address": "127.0.0.1:4444",
    "env": "dev",
    "ping_cycle": 1,
    "failure_threshold": 5,
    "pepper": "secret-pepper-key",
    "hmac_Key": "secret-hmac-key",
    "database": {
        "db_dialect": "sqlite",
        "host": "127.0.0.1",
        "port": 0,
        "usr": "",
        "password": "",
        "name": "testdb.sqlite"
    },
    "cert_file": "",
    "key_file": "",
    "rsa256_priv_key_file": "",
    "rsa256_pub_key_file": "",
    "rsa384_priv_key_file": "",
    "rsa384_pub_key_file": "",
    "rsa512_priv_key_file": "",
    "rsa512_pub_key_file": "",
    "ecdsa256_priv_key_file": "",
    "ecdsa256_pub_key_file": "",
    "ecdsa384_priv_key_file": "jwtkeys/ecdsa384/ec384.priv.pem",
    "ecdsa384_pub_key_file": "jwtkeys/ecdsa384/ec384.pub.pem",
    "ecdsa521_priv_key_file": "",
    "ecdsa521_pub_key_file": "",
    "jwt_sign_method": "ES384",
    "jwt_lifetime": 120,
    "service_activations": [
        {
            "service_name": "Library",
            "service_active": true
        },
        {
            "service_name": "Book",
            "service_active": true
        }
    ]
}