Skip to content
This repository has been archived by the owner on Mar 1, 2023. It is now read-only.

Commit

Permalink
Add RedisConfigurationProvider
Browse files Browse the repository at this point in the history
This abstracts away where we're getting our redis URL from so that we
can support either the existing behavior, or an override of `REDIS_URL`
in the environment.
  • Loading branch information
Mike Stallard committed Oct 18, 2018
1 parent d0f1f3c commit b6845d4
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 3 deletions.
3 changes: 2 additions & 1 deletion api/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ gem 'rails', '5.2.1'
gem 'activeadmin'
gem 'addressable'
gem 'bcrypt'
gem 'cf-app-utils'
gem 'devise'
gem 'friendly_id', '5.1.0'
gem 'inherited_resources'
Expand All @@ -56,6 +57,7 @@ group :development, :test do
gem 'shoulda-matchers'
gem 'webmock'
gem 'tzinfo-data'
gem 'climate_control'
gem 'action-cable-testing'
end

Expand All @@ -67,7 +69,6 @@ group :development do
end

group :production do
gem 'cf-app-utils'
gem 'redis', '~> 3.3.3'
gem 'mysql2'
gem 'pg'
Expand Down
2 changes: 2 additions & 0 deletions api/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ GEM
uniform_notifier (~> 1.11.0)
byebug (10.0.2)
cf-app-utils (0.6)
climate_control (0.2.0)
coderay (1.1.2)
coffee-rails (4.2.2)
coffee-script (>= 2.2.0)
Expand Down Expand Up @@ -314,6 +315,7 @@ DEPENDENCIES
bcrypt
bullet
cf-app-utils
climate_control
devise
dotenv-rails
friendly_id (= 5.1.0)
Expand Down
2 changes: 1 addition & 1 deletion api/config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.

config.autoload_paths << Rails.root.join('lib', 'configurations')
config.session_time = (ENV['SESSION_TIME'] || 120).to_i.minutes
end
end
2 changes: 1 addition & 1 deletion api/config/cable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ test:

production:
adapter: redis
url: <%= ENV["RAILS_ENV"] == "production" && (c = CF::App::Credentials.find_by_service_tag('redis')) && Addressable::URI.new(scheme: 'redis', host: c["hostname"] || c.fetch('host'), password: c['password'], port: c.fetch('port')).to_s %>
url: <%= RedisConfigurationProvider.new.redis_config %>
44 changes: 44 additions & 0 deletions api/lib/configurations/redis_configuration_provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#
# Postfacto, a free, open-source and self-hosted retro tool aimed at helping
# remote teams.
#
# Copyright (C) 2016 - Present Pivotal Software, Inc.
#
# This program is free software: you can redistribute it and/or modify
#
# it under the terms of the GNU Affero General Public License as
#
# published by the Free Software Foundation, either version 3 of the
#
# License, or (at your option) any later version.
#
#
#
# This program is distributed in the hope that it will be useful,
#
# but WITHOUT ANY WARRANTY; without even the implied warranty of
#
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#
# GNU Affero General Public License for more details.
#
#
#
# You should have received a copy of the GNU Affero General Public License
#
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
require 'cf-app-utils'

class RedisConfigurationProvider
def redis_config
return nil unless ENV['RAILS_ENV'] == 'production'
return ENV['REDIS_URL'] unless ENV['REDIS_URL'].nil?

unless ENV['VCAP_SERVICES'].nil?
c = CF::App::Credentials.find_by_service_tag('redis')
host = c['hostname'] || c.fetch('host')
Addressable::URI.new(scheme: 'redis', host: host, password: c['password'], port: c.fetch('port')).to_s
end
end
end
146 changes: 146 additions & 0 deletions api/spec/lib/redis_configuration_provider_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#
# Postfacto, a free, open-source and self-hosted retro tool aimed at helping
# remote teams.
#
# Copyright (C) 2016 - Present Pivotal Software, Inc.
#
# This program is free software: you can redistribute it and/or modify
#
# it under the terms of the GNU Affero General Public License as
#
# published by the Free Software Foundation, either version 3 of the
#
# License, or (at your option) any later version.
#
#
#
# This program is distributed in the hope that it will be useful,
#
# but WITHOUT ANY WARRANTY; without even the implied warranty of
#
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#
# GNU Affero General Public License for more details.
#
#
#
# You should have received a copy of the GNU Affero General Public License
#
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
require 'redis_configuration_provider'
require 'climate_control'

describe RedisConfigurationProvider do
let(:subject) { RedisConfigurationProvider.new }

describe '#redis_config' do
around do |example|
ClimateControl.modify('RAILS_ENV' => rails_env, 'VCAP_SERVICES' => vcap_services, 'REDIS_URL' => redis_url) do
example.run
end
end

context 'when running outside of production' do
let(:rails_env) { 'development' }
let(:vcap_services) { 'unused-vcap-services-value' }
let(:redis_url) { 'unused-redis-url=-value' }

it 'is nil ' do
expect(subject.redis_config).to be_nil
end
end

context 'when running in production' do
let(:rails_env) { 'production' }

context 'when REDIS_URL is defined in the environment' do
let(:redis_url) { 'redis://user:pass@hostname.com:420' }

context 'when VCAP_SERVICES is defined in the environment' do
let(:vcap_services) do
{
'redis' => [
{
'tags' => 'redis',
'credentials' => {
'hostname' => 'hostname',
'password' => 'pass',
'port' => 234
}
}
]
}.to_json
end

it 'returns the url from REDIS_URL' do
expect(subject.redis_config).to eq('redis://user:pass@hostname.com:420')
end
end

context 'when VCAP_SERVICES is NOT defined in the environment' do
let(:vcap_services) { nil }
it 'returns the url from REDIS_URL' do
expect(subject.redis_config).to eq('redis://user:pass@hostname.com:420')
end
end
end

context 'when REDIS_URL is not defined in the environment' do
let(:redis_url) { nil }

context 'when VCAP_SERVICES is defined in the environment' do
context 'and host is declared as host' do
let(:vcap_services) do
{
'redis' => [
{
'tags' => 'redis',
'credentials' => {
'hostname' => 'hostname',
'password' => 'pass',
'port' => 234
}
}
]
}.to_json
end

it 'builds a URL based upon the redis service described by vcap services' do
expect(subject.redis_config).to eq('redis://:pass@hostname:234')
end
end

context 'and host is declared as hostname' do
let(:vcap_services) do
{
'redis' => [
{
'tags' => 'redis',
'credentials' => {
'host' => 'host',
'password' => 'pass',
'port' => 234
}
}
]
}.to_json
end

it 'builds a URL based upon the redis service described by vcap services' do
expect(subject.redis_config).to eq('redis://:pass@host:234')
end
end
end

context 'when VCAP_SERVICES is NOT defined in the environment' do
let(:vcap_services) { nil }

it 'returns nil' do
expect(subject.redis_config).to be_nil
end
end
end
end
end
end

0 comments on commit b6845d4

Please sign in to comment.