Contract for Deployable Apps

This contract specifies the behaviour which a TIM Group Application SHALL [1] provide.

There are two APIs. The Info-API (which exposes information about the state of the App) MUST be provided. The Enablement-API OPTIONALLY can be implemented by the application, however implementation by the load balancer or other part of the Infrastructure is RECOMMENDED.

Both APIs are REQUIRED to be implemented for an application to be managed by the standard deployment and orchestration tools.

General

All APIs are implemented as either HTTP GET or PUT requests.

All requests are text/plain: UTF-8.

All requests MUST return status code 200 whether or not the response body indicates a positive or negative response.

All response bodies are REQUIRED to be exact strings. Leading or trailing whitespace is not permitted.

All the specified URLs MUST be served at the root level.

All requests are RECOMMENDED be "very low cost". That is, it MUST be acceptable to call the requests every second without causing significant load.

All requests MUST be "fast". That is, return within tens of milliseconds.

Client applications MUST NOT hold open connections. If you do this, the application continues serving requests after it has been taken out of the load balancer.

Configuration

There must be a configuration file (config.properties) used to launch the application. At minimum it should contain: port=9999 (Note that we would like to rename this to application.server.port)

This will be used during deployment (see below)

API's

All new applications must implement the Infra following API's before they can be deployed.

Information

The purpose of this API is to expose certain aspects of the App's state to the orchestration tool. All these are GET requests.

URLpositive responsenegative response
/info/health healthy ill
/info/version version number as string n/a
/info/stoppable safe unwise
health

The responsibility for choosing which response to return is the App's alone. If the App returns "ill", the orchestration tool will take the App out of service.

stoppable

The App should be designed to be crash-safe, so that outages beyond its control do not, for example, lose data. The "correct" way to shut down an App is to send it a kill signal.

This item provides information to the orchestration about whether 'now is a good time' for the App to be killed. There is no guarantee that the App will not be killed when it is returning "unwise". Thus it should try to minimize the time it is in the "unwise" state.

version

The App should return a version number in the 'three numbers separated by periods' format.

title

Currently, the title resource is not required. If implemented, the App should return a title string.

Enablement (Participation)

The purpose of this API is to support traffic direction (load balancing) by the orchestration tool.

The Enablement (Participation) API does not need to be implemented by the application, it is handled by Tatin. This information remains for reference only.

URLpositive responsenegative response
/info/participation enabled disabled

Both a GET and a PUT are defined on this URL. The GET retrieves the current state, and the PUT sets the state.

This interface it should just retain (and return) the last state set. The state should begin as "disabled".

Testing your API implementation

A tool is available to test the compliance of your application with the Infra contract.

Commit your Test Configuration file(s)

First off you need to add a simple configuration to the deployment-contract-test repo, please use the quick guide:

git clone git@git:deployment-contract-test
cd deployment-contract-test/config/
mkdir <My Application>
cp /path/to/your/simple/config/config.properties .
git commit -a 
git push
Create a Jenkins job to test your implementation

Please use the following quick guide: - Create a new job in Jenkins - Name: -Contract - Under "Copy existing job" put: XXX-Deployment-Contract - Press "OK"

Link the Jenkins contract job to your build

The final step is to connect this job to the upstream build of your application (enables continous deployment).

  • Edit your -Contract job in Jenkins, Remove the default value from the version parameter. Save changes
  • Edit your job in Jenkins, set the following options:
    • Tick "Trigger parameterized build on other projects"
    • Project to build "-Contract"
    • Trigger when build is: "STABLE"
    • Add the following build parameter: version=1.0.$BUILD_NUMBER
    • Save changes

The next time your upstream project builds successfully it will run the Infra contract job.

Deployment

All applications should be delivered as a an executable "jar" or "war" file.

This package should contain a manifest with a "main" method.

Example:

java -jar myjar.jar config.properties</code>

You can get the jenkins build number as an environment variable in your build scripts, i.e:

def majorVersion = 1
def minorVersion = 0
def patchVersion = System.getenv('BUILD_NUMBER')
version = "${majorVersion}.${minorVersion}.${patchVersion}"
Proxies / environment

If your application is deployed behind a proxy layer, then the following headers SHALL be present:

  • X-Forwarded-Proto - will contain the value 'https' if the service is being presented behind a proxy which removes SSL
  • X-Forwarded-Host - The vhost name the original request was sent to.
  • X-Forwarded-For - The hostname or IP address of the original client.

[1] The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119

Fork me on GitHub