Compare commits

...

4 Commits

Author SHA1 Message Date
Konstantin Haase
600aeabad9 v3: implement user and org sync queries 2015-03-31 17:02:07 +02:00
Konstantin Haase
841aaef368 add debug output for sidekiq on staging 2015-03-31 16:51:37 +02:00
Konstantin Haase
b30aa0e8c5 v3: make create request specs use new sidekiq abstraction, so it does not mess with Sidekiq internals 2015-03-31 16:31:58 +02:00
Konstantin Haase
b7466074ca first stab at user/org sync 2015-03-30 12:38:05 +02:00
14 changed files with 142 additions and 23 deletions

View File

@ -50,7 +50,7 @@ GIT
GIT
remote: git://github.com/travis-ci/travis-core.git
revision: ba10e214824632f15598555a2634ce3347d2f227
revision: 4834399048b8c9cff4882d435f770826930665f6
specs:
travis-core (0.0.1)
actionmailer (~> 3.2.19)
@ -81,7 +81,7 @@ GIT
GIT
remote: git://github.com/travis-ci/travis-support.git
revision: 4fdd220ed7b06a12951e5d74a763c05a80eb0d20
revision: e7f81093f83bd029cca6508739c5720e57e3d571
specs:
travis-support (0.0.1)

View File

@ -48,6 +48,10 @@ module Travis::API::V3
unrestricted_api?
end
def user_writable?(user)
user and user == self.user
end
def repository_visible?(repository)
return true if unrestricted_api? and not repository.private?
private_repository_visible?(repository)

View File

@ -0,0 +1,20 @@
require 'sidekiq'
module Travis::API::V3
module Extensions
module Sidekiq
module Client
def push(item)
Travis.logger.info("Sidekiq job scheduled: #{item.inspect}") if debug_push?
super
end
def debug_push?
Travis.env == 'development'.freeze or Travis.env == 'staging'.freeze
end
end
::Sidekiq::Client.send(:prepend, Client)
end
end
end

View File

@ -6,5 +6,10 @@ module Travis::API::V3
return Models::Organization.find_by_id(id) if id
raise WrongParams, 'missing organization.id'.freeze
end
def sync(org = find)
user_query = Queries::User.new(params, main_type)
org.users.each { |user| user_query.sync(user) }
end
end
end

View File

@ -6,5 +6,12 @@ module Travis::API::V3
return Models::User.find_by_id(id) if id
raise WrongParams, 'missing user.id'.freeze
end
def sync(user = find, force: false)
return false if user.syncing? and not force
perform_async(:sync_user, user)
user.update_column(:is_syncing, true)
true
end
end
end

View File

@ -32,12 +32,7 @@ module Travis::API::V3
end
def perform_async(identifier, *args)
class_name, queue = @@sidekiq_cache[identifier] ||= [
"Travis::Sidekiq::#{identifier.to_s.camelcase}".freeze,
identifier.to_s.pluralize.freeze
]
::Sidekiq::Client.push('queue'.freeze => queue, 'class'.freeze => class_name, 'args'.freeze => args)
Sidekiqs[identifier].perform_async(*args)
end
def includes?(key)

View File

@ -34,8 +34,9 @@ module Travis::API::V3
resource :user do
route '/user'
get :current
get :find, '/{user.id}'
get :current
get :find, '/{user.id}'
post :sync, '/{user.id}/sync'
end
resource :organization do

View File

@ -0,0 +1,7 @@
module Travis::API::V3
class Services::Organization::Sync < Service
def run!
query.sync if access_control.writable? find
end
end
end

View File

@ -0,0 +1,7 @@
module Travis::API::V3
class Services::User::Sync < Service
def run!
query.sync if access_control.writable? find
end
end
end

View File

@ -0,0 +1,30 @@
module Travis::API::V3
class Sidekiq
def self.client
@client ||= ::Sidekiq::Client
end
def self.client=(value)
@client = value
end
attr_accessor :class_name, :queue, :identifier
attr_writer :client
def initialize(identifier, class_name: nil, queue: nil, client: nil)
@identifier = identifier
@class_name = class_name || identifier
@class_name = "Travis::Sidekiq::%s".freeze % @class_name.to_s.camelcase if @class_name.is_a? Symbol
@queue = queue.to_s || "default".freeze
@client = client
end
def client
@client || self.class.client
end
def perform_async(*args)
client.push('queue'.freeze => queue, 'class'.freeze => class_name, 'args'.freeze => args)
end
end
end

View File

@ -0,0 +1,8 @@
module Travis::API::V3
module Sidekiqs
extend ConstantResolver
BuildRequest = Sidekiq.new(:build_request, queue: :build_requests)
SyncUser = Sidekiq.new(:synchronize_user, queue: :user_sync)
end
end

View File

@ -104,7 +104,11 @@ describe Travis::API::V3::ServiceIndex do
"find"=>
[{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}user/{user.id}"}]},
"uri_template"=>"#{path}user/{user.id}"}],
"sync"=>
[{"@type"=>"template",
"request_method"=>"POST",
"uri_template"=>"#{path}user/{user.id}/sync"}]},
"attributes"=>["id", "login", "name", "github_id", "is_syncing", "synced_at"]}}
}

View File

@ -2,20 +2,16 @@ require 'spec_helper'
describe Travis::API::V3::Services::Requests::Create do
let(:repo) { Travis::API::V3::Models::Repository.where(owner_name: 'svenfuchs', name: 'minimal').first }
let(:sidekiq_payload) { JSON.load(Sidekiq::Client.last['args'].last[:payload]).deep_symbolize_keys }
let(:sidekiq_requests) { [] }
before { repo.requests.each(&:delete) }
before do
Travis::Features.stubs(:owner_active?).returns(true)
@original_sidekiq = Sidekiq::Client
Sidekiq.send(:remove_const, :Client) # to avoid a warning
Sidekiq::Client = []
let(:sidekiq_payload) do
expect(sidekiq_requests).not_to be_empty, 'expected at least one sidekiq request to be sent, none sent'
JSON.load(sidekiq_requests.last['args'].last[:payload]).deep_symbolize_keys
end
after do
Sidekiq.send(:remove_const, :Client) # to avoid a warning
Sidekiq::Client = @original_sidekiq
end
before { Travis::API::V3::Sidekiq.client = sidekiq_requests }
after { Travis::API::V3::Sidekiq.client = nil }
describe "not authenticated" do
before { post("/v3/repo/#{repo.id}/requests") }
@ -104,8 +100,8 @@ describe Travis::API::V3::Services::Requests::Create do
config: {}
}}
example { expect(Sidekiq::Client.last['queue']).to be == 'build_requests' }
example { expect(Sidekiq::Client.last['class']).to be == 'Travis::Sidekiq::BuildRequest' }
example { expect(sidekiq_requests.last['queue']).to be == 'build_requests' }
example { expect(sidekiq_requests.last['class']).to be == 'Travis::Sidekiq::BuildRequest' }
describe "setting id has no effect" do
let(:params) {{ id: 42 }}

View File

@ -0,0 +1,35 @@
require 'spec_helper'
describe Travis::API::V3::Services::User::Find do
let(:user) { User.find_by_login('svenfuchs') }
let(:token) { Travis::Api::App::AccessToken.create(user: user, app_id: 1) }
let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}" }}
before do
Travis::Features.stubs(:owner_active?).returns(true)
@original_sidekiq = Sidekiq::Client
Sidekiq.send(:remove_const, :Client) # to avoid a warning
Sidekiq::Client = []
end
after do
Sidekiq.send(:remove_const, :Client) # to avoid a warning
Sidekiq::Client = @original_sidekiq
end
describe "authenticated as user with access" do
before { post("/v3/user/#{user.id}/sync", {}, headers) }
example { expect(last_response.status).to be 202 }
# example { expect(JSON.load(body)).to be == {
# "@type" => "user",
# "@href" => "/v3/user/#{user.id}",
# "id" => user.id,
# "login" => "svenfuchs",
# "name" =>"Sven Fuchs",
# "github_id" => user.github_id,
# "is_syncing" => user.is_syncing,
# "synced_at" => user.synced_at
# }}
end
end