Skip to content

Commit

Permalink
Add SolrEndpoint configuration to allow accounts to point at differen…
Browse files Browse the repository at this point in the history
…t solr urls
  • Loading branch information
cbeer committed Apr 18, 2016
1 parent 6340e8f commit b7741dd
Show file tree
Hide file tree
Showing 14 changed files with 184 additions and 4 deletions.
2 changes: 1 addition & 1 deletion app/controllers/accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ def destroy

# Never trust parameters from the scary internet, only allow the white list through.
def account_params
params.require(:account).permit(:tenant, :cname)
params.require(:account).permit(:tenant, :cname, solr_endpoint_attributes: [:id, :url])
end
end
5 changes: 5 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ApplicationController < ActionController::Base
helper_method :peek_enabled?

before_action :require_active_account!, if: :multitenant?
before_action :set_account_specific_connections!

rescue_from Apartment::TenantNotFound do
redirect_to accounts_path
Expand All @@ -34,6 +35,10 @@ def require_active_account!
raise Apartment::TenantNotFound, "No tenant for #{request.host}" unless current_account
end

def set_account_specific_connections!
current_account.switch! if current_account
end

def multitenant?
Settings.multitenant
end
Expand Down
14 changes: 14 additions & 0 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,21 @@ class Account < ActiveRecord::Base
validates :tenant, presence: true, uniqueness: true
validates :cname, presence: true, uniqueness: true

belongs_to :solr_endpoint

before_create :create_default_solr_endpoint

accepts_nested_attributes_for :solr_endpoint, update_only: true

# @return [Account]
def self.from_request(request)
find_by(cname: request.host)
end

def switch!
solr_endpoint.switch! if solr_endpoint
end

def save_and_create_tenant(&block)
save.tap do |result|
break unless result
Expand All @@ -23,4 +33,8 @@ def create_tenant
yield if block_given?
end
end

def create_default_solr_endpoint
self.solr_endpoint ||= create_solr_endpoint(SolrEndpoint.default_options)
end
end
3 changes: 3 additions & 0 deletions app/models/endpoint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Endpoint < ActiveRecord::Base
has_one :account
end
20 changes: 20 additions & 0 deletions app/models/solr_endpoint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class SolrEndpoint < Endpoint
store :options, accessors: [:url]

def self.default_options
ActiveFedora::SolrService.instance.conn.options.slice(:url)
end

def connection
RSolr.connect(connection_options)
end

def connection_options
options.reverse_merge(ActiveFedora::SolrService.instance.conn.options)
end

def switch!
ActiveFedora::SolrService.register(url, connection_options)
Blacklight.instance_variable_set(:@default_index, connection)
end
end
9 changes: 9 additions & 0 deletions app/views/accounts/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
<%= f.label :cname %><br>
<%= f.text_field :cname, class: 'form-control' %>
</div>

<%= f.fields_for :solr_endpoint do |s| %>
<h3>Solr Endpoint</h3>
<div class="form-group">
<%= s.label :url %><br>
<%= s.text_field :url, class: 'form-control' %>
</div>
<% end %>

<div class="actions">
<%= f.submit class: 'btn btn-primary' %>
</div>
Expand Down
2 changes: 1 addition & 1 deletion config/initializers/apartment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# Add any models that you do not want to be multi-tenanted, but remain in the global (public) namespace.
# A typical example would be a Customer or Tenant model that stores each Tenant's information.
#
config.excluded_models = %w{ Account }
config.excluded_models = %w{ Account Endpoint SolrEndpoint }

# In order to migrate all of your Tenants you need to provide a list of Tenant names to Apartment.
# You can make this dynamic by providing a Proc object to be called on migrations.
Expand Down
10 changes: 10 additions & 0 deletions db/migrate/20160414155644_create_endpoints.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CreateEndpoints < ActiveRecord::Migration
def change
create_table :endpoints do |t|
t.string :type
t.binary :options

t.timestamps null: false
end
end
end
6 changes: 6 additions & 0 deletions db/migrate/20160414155816_add_solr_endpoint_to_account.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddSolrEndpointToAccount < ActiveRecord::Migration
def change
add_column :accounts, :accounts, :string
add_column :accounts, :solr_endpoint_id, :integer
end
end
13 changes: 11 additions & 2 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
create_table "accounts", force: :cascade do |t|
t.string "tenant"
t.string "cname"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "accounts"
t.integer "solr_endpoint_id"
end

add_index "accounts", ["cname", "tenant"], name: "index_accounts_on_cname_and_tenant", using: :btree
Expand Down Expand Up @@ -73,6 +75,13 @@
add_index "domain_terms_local_authorities", ["domain_term_id", "local_authority_id"], name: "dtla_by_ids2", using: :btree
add_index "domain_terms_local_authorities", ["local_authority_id", "domain_term_id"], name: "dtla_by_ids1", using: :btree

create_table "endpoints", force: :cascade do |t|
t.string "type"
t.binary "options"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "featured_works", force: :cascade do |t|
t.integer "order", default: 5
t.string "generic_work_id"
Expand Down
14 changes: 14 additions & 0 deletions spec/controllers/accounts_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,18 @@
end
end
end

describe 'account dependency switching' do
let(:account) { FactoryGirl.create(:account) }

before do
Site.update(account: account)
allow(controller).to receive(:current_account).and_return(account)
end

it 'switches account information' do
expect(account).to receive(:switch!)
get :show, { id: account.to_param }, valid_session
end
end
end
36 changes: 36 additions & 0 deletions spec/features/accounts_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'rails_helper'

RSpec.describe 'Accounts administration' do
context 'as an superadmin' do
let(:user) { FactoryGirl.create(:superadmin) }
let(:account) { FactoryGirl.create(:account) }

before do
login_as(user, scope: :user)
end

it 'changes the associated cname' do
visit edit_account_path(account)

fill_in 'Cname', with: 'example.com'

click_on 'Update Account'

account.reload

expect(account.cname).to eq 'example.com'
end

it 'changes the solr endpoint url' do
visit edit_account_path(account)

fill_in 'Url', with: 'http://example.com/solr/'

click_on 'Update Account'

account.reload

expect(account.solr_endpoint.url).to eq 'http://example.com/solr/'
end
end
end
31 changes: 31 additions & 0 deletions spec/models/account_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,28 @@
end
end

describe '#switch!' do
let!(:old_default_index) { Blacklight.default_index }

before do
subject.build_solr_endpoint.update(url: 'http://example.com/solr/')
subject.switch!
end

after do
ActiveFedora::SolrService.reset!
Blacklight.instance_variable_set(:@default_index, old_default_index)
end

it 'switches the ActiveFedora solr connection' do
expect(ActiveFedora::SolrService.instance.conn.uri.to_s).to eq 'http://example.com/solr/'
end

it 'switches the Blacklight solr conection' do
expect(Blacklight.default_index.uri.to_s).to eq 'http://example.com/solr/'
end
end

describe '#save_and_create_tenant' do
subject { described_class.new(tenant: 'x', cname: 'x') }

Expand All @@ -29,4 +51,13 @@
end
end
end

describe '#solr_endpoint' do
subject { FactoryGirl.create(:account) }

it 'has a default solr endpoint configuration' do
expect(subject.solr_endpoint).to be_present
expect(subject.solr_endpoint.url).to eq SolrEndpoint.default_options[:url]
end
end
end
23 changes: 23 additions & 0 deletions spec/models/solr_endpoint_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'rails_helper'

RSpec.describe SolrEndpoint do
subject { described_class.new url: 'http://example.com/solr/' }
describe '.default_attributes' do
it 'uses the configured application settings' do
expect(described_class.default_options).to eq url: ActiveFedora::SolrService.instance.conn.options[:url]
end
end

describe '#connection_options' do
it 'merges the model attributes with the application settings' do
expect(subject.connection_options).to include url: 'http://example.com/solr/', read_timeout: 120
end
end

describe '#connection' do
it 'initializes an RSolr connection with the model options' do
expect(subject.connection).to be_a_kind_of RSolr::Client
expect(subject.connection.uri.to_s).to eq 'http://example.com/solr/'
end
end
end

0 comments on commit b7741dd

Please sign in to comment.