Skip to content

Setting up the development environment

Renato Mascarenhas edited this page Jun 29, 2016 · 4 revisions

Setting up a new project from scratch can be an intimidating and painful task. This guide aims to be a step-by-step guide to help you to get the development environment set up.

First things first

The first step is to clone the project:

$ git clone git@github.com:roomorama/concierge.git

and install its dependencies:

$ bundle

Note that some of the dependencies of Concierge require packages to be installed on the machine beforehand. Namely, these are:

  • pg: Requires the PostgreSQL server and client libraries
  • patron: requires libcurl
  • yajl-ruby: requires yajl to be installed

Environment Variables

Environment variables are managed by the .env file. The project contains a .env.example file that can be used to start developing, so you can just make a copies of environment configuration example file for test and development environments:

$ cp .env.example .env.development
$ cp .env.example .env.test

Note that one variable declared on that file is CONCIERGE_DATABASE_URL. That variable should be declared according to the way the database is configured on the running machine. The expected format is:

CONCIERGE_DATABASE_URL="postgres://username:password@0.0.0.0:5432/concierge_development"

Configuring the database

If the last step above was successful, you can create the database and apply migrations with the following commands:

$ bundle exec hanami db create
$ bundle exec hanami db migrate

Start Concierge!

$ hanami server 

Concierge makes sure that all required environment variables are properly defined when the application is booting. If you get an error message while booting the application due to a missing environment variable, it means the .env.example file in the repository is not complete. Let us know if that is the case and we will help you get everything set up (and update the .env.example file accordingly.)

Logging-in to the web interface

The web interface (the production equivalent located at https://concierge-web.roomorama.com) requires HTTP Basic Authentication in order for access to be guaranteed. On development, it can be accessed at localhost:2300/web. By default, the credentials for the development environment are admin, for both username and password.

Testing Webhooks

Roomorama's webhooks include a Content-Signature HTTP header to every request, which contains the signed request payload using a secret that is only known by Roomorama itself and the supplier. Secrets are configured via environment variables, in environment variables that look like ROOMORAMA_SECRET_*.

To test that a given supplier integration works in the whole framework, it is necessary:

  • set up required credentials at config/credentials/development.yml
  • create a test JSON file to test
  • sign the JSON file above according to the content of the corresponding signature.

For this example, we are going to run a quote operation for the AtLeisure supplier, as a test. Assuming the credentials are already configured (credentials for suppliers should be requested case-by-case), the next step would be to create a valid JSON payload to use as input of the API call.

Such payload could be

% cat webhook.json 
{
  "event": "quote_instant",
  "inquiry": {
    "check_in":    "2016-09-12",
    "check_out":   "2016-09-15",
    "subtotal":    100,
    "num_guests":  2,

    "room": {
      "property_id": "IT-53017-17"
    },

    "user": {
      "first_name":   "Roomorama",
      "last_name":    "Guest",
      "email":        "developers@roomorama.com",
      "phone_number": "+1 93849238"
    }
  }
}

Using the default secret for AtLeisure in the .env.example file (which is xxx), we can then sign the payload above using a simple script, such as:

#!/usr/bin/env ruby

require "openssl"
require "base64"

encoded = Base64.encode64(File.read(ARGV[0]))
digest  = OpenSSL::Digest.new("sha1")
puts OpenSSL::HMAC.hexdigest(digest, ARGV[1], encoded)
% ./sign webhook.json xxx
2f469f1d71986f08a468cfe2a00223ad15c09d0d

Which allows us to, finally, make a successful request to our local Concierge application. Notice that we need to specifiy the /api namespace on development, which does not exist on staging/production environments.

% curl -v -H "Content-Type: application/json" -H "Content-Signature: 2f469f1d71986f08a468cfe2a00223ad15c09d0d" --data-binary @webhook.json localhost:2300/api/atleisure/quote
*   Trying ::1...
* Connected to localhost (::1) port 2300 (#0)
> POST /api/atleisure/quote HTTP/1.1
> Host: localhost:2300
> User-Agent: curl/7.48.0
> Accept: */*
> Content-Type: application/json
> Content-Signature: 2f469f1d71986f08a468cfe2a00223ad15c09d0d
> Content-Length: 393
> 
* upload completely sent off: 393 out of 393 bytes
< HTTP/1.1 200 OK 
< Content-Type: application/json; charset=utf-8
< Server: WEBrick/1.3.1 (Ruby/2.3.0/2015-12-25)
< Date: Fri, 10 Jun 2016 09:58:19 GMT
< Content-Length: 378
< Connection: Keep-Alive
< 
* Connection #0 to host localhost left intact
{"event":"price_check","inquiry":{"check_in":"2016-09-12","check_out":"2016-09-15","subtotal":1156,"room":{"property_id":"IT-53017-17","num_guests":2},"user":{"first_name":"Roomorama","last_name":"Guest","email":"developers@roomorama.com","phone_number":"+1 93849238"},"base_rental":1156,"currency_code":"EUR","tax":0,"processing_fee":0,"extra_guests_surcharge":0,"total":1156}}