Commit d5b673da authored by James Lopez's avatar James Lopez

more refactoring and added some auth checks

parent 9c995725
...@@ -50,7 +50,7 @@ module Projects ...@@ -50,7 +50,7 @@ module Projects
end end
def options def options
@options ||= { from: start_date(events_params) } @options ||= { from: start_date(events_params), current_user: current_user }
end end
def events_params def events_params
......
This diff is collapsed.
module Gitlab module Gitlab
module CycleAnalytics module CycleAnalytics
class BaseEvent class BaseEvent
extend MetricsTables include MetricsTables
class << self attr_reader :stage, :start_time_attrs, :end_time_attrs, :projections, :query
attr_reader :stage, :start_time_attrs, :end_time_attrs, :projections
def order def initialize(project:, options:)
@order || @start_time_attrs @query = EventsQuery.new(project: project, options: options)
@project = project
@options = options
end
def fetch
@query.execute(self).map do |event|
serialize(event) if has_permission?(event['id'])
end end
end
def query(_base_query); end def custom_query(_base_query); end
def fetch(query) def order
query.execute(self).map { |event| serialize(event, query) } @order || @start_time_attrs
end end
private private
def serialize(_event, _query) def serialize(_event)
raise NotImplementedError.new("Expected #{self.name} to implement serialize(event, query)") raise NotImplementedError.new("Expected #{self.name} to implement serialize(event)")
end end
def has_permission?(_id)
true
end end
end end
end end
......
module Gitlab module Gitlab
module CycleAnalytics module CycleAnalytics
class CodeEvent < BaseEvent class CodeEvent < BaseEvent
@stage = :code def initialize(*args)
@start_time_attrs = issue_metrics_table[:first_mentioned_in_commit_at] @stage = :code
@start_time_attrs = issue_metrics_table[:first_mentioned_in_commit_at]
@end_time_attrs = mr_table[:created_at]
@projections = [mr_table[:title],
mr_table[:iid],
mr_table[:id],
mr_table[:created_at],
mr_table[:state],
mr_table[:author_id]]
@order = mr_table[:created_at]
@end_time_attrs = mr_table[:created_at] super(*args)
end
@projections = [mr_table[:title],
mr_table[:iid],
mr_table[:id],
mr_table[:created_at],
mr_table[:state],
mr_table[:author_id]]
@order = mr_table[:created_at] private
def self.serialize(event, query) def serialize(event)
event['author'] = User.find(event.delete('author_id')) event['author'] = User.find(event.delete('author_id'))
AnalyticsMergeRequestSerializer.new(project: query.project).represent(event).as_json AnalyticsMergeRequestSerializer.new(project: @project).represent(event).as_json
end
def has_permission?(id)
@options[:current_user].can?(:read_merge_request, MergeRequest.find(id))
end end
end end
end end
......
module Gitlab
module CycleAnalytics
class TestEvent < BaseEvent
@start_time_attrs = mr_table[:created_at]
@end_time_attrs = mr_metrics_table[:merged_at]
@projections = [mr_table[:title],
mr_table[:iid],
mr_table[:id],
mr_table[:created_at],
mr_table[:state],
mr_table[:author_id]]
end
end
end
...@@ -3,35 +3,35 @@ module Gitlab ...@@ -3,35 +3,35 @@ module Gitlab
class Events class Events
def initialize(project:, options:) def initialize(project:, options:)
@project = project @project = project
@query = EventsQuery.new(project: project, options: options) @options = options
end end
def issue_events def issue_events
IssueEvent.fetch(@query) IssueEvent.new(project: @project, options: @options).fetch
end end
def plan_events def plan_events
PlanEvent.fetch(@query) PlanEvent.new(project: @project, options: @options).fetch
end end
def code_events def code_events
CodeEvent.fetch(@query) CodeEvent.new(project: @project, options: @options).fetch
end end
def test_events def test_events
TestEvent.fetch(@query) TestEvent.new(project: @project, options: @options).fetch
end end
def review_events def review_events
ReviewEvent.fetch(@query) ReviewEvent.new(project: @project, options: @options).fetch
end end
def staging_events def staging_events
StagingEvent.fetch(@query) StagingEvent.new(project: @project, options: @options).fetch
end end
def production_events def production_events
ProductionEvent.fetch(@query) ProductionEvent.new(project: @project, options: @options).fetch
end end
end end
end end
......
...@@ -22,7 +22,7 @@ module Gitlab ...@@ -22,7 +22,7 @@ module Gitlab
base_query = @fetcher.base_query_for(@stage_class.stage) base_query = @fetcher.base_query_for(@stage_class.stage)
diff_fn = @fetcher.subtract_datetimes_diff(base_query, @stage_class.start_time_attrs, @stage_class.end_time_attrs) diff_fn = @fetcher.subtract_datetimes_diff(base_query, @stage_class.start_time_attrs, @stage_class.end_time_attrs)
@stage_class.query(base_query) @stage_class.custom_query(base_query)
base_query.project(extract_epoch(diff_fn).as('total_time'), *@stage_class.projections).order(@stage_class.order.desc) base_query.project(extract_epoch(diff_fn).as('total_time'), *@stage_class.projections).order(@stage_class.order.desc)
end end
......
module Gitlab module Gitlab
module CycleAnalytics module CycleAnalytics
class IssueEvent < BaseEvent class IssueEvent < BaseEvent
@stage = :issue def initialize(*args)
@start_time_attrs = issue_table[:created_at] @stage = :issue
@start_time_attrs = issue_table[:created_at]
@end_time_attrs = [issue_metrics_table[:first_associated_with_milestone_at],
issue_metrics_table[:first_added_to_board_at]]
@projections = [issue_table[:title],
issue_table[:iid],
issue_table[:id],
issue_table[:created_at],
issue_table[:author_id]]
@end_time_attrs = [issue_metrics_table[:first_associated_with_milestone_at], super(*args)
issue_metrics_table[:first_added_to_board_at]] end
@projections = [issue_table[:title], private
issue_table[:iid],
issue_table[:id],
issue_table[:created_at],
issue_table[:author_id]]
def self.serialize(event, query) def serialize(event)
event['author'] = User.find(event.delete('author_id')) event['author'] = User.find(event.delete('author_id'))
AnalyticsIssueSerializer.new(project: query.project).represent(event).as_json AnalyticsIssueSerializer.new(project: @project).represent(event).as_json
end
def has_permission?(id)
@options[:current_user].can?(:read_issue, Issue.find(id))
end end
end end
end end
......
module Gitlab module Gitlab
module CycleAnalytics module CycleAnalytics
class PlanEvent < BaseEvent class PlanEvent < BaseEvent
@stage = :plan def initialize(*args)
@start_time_attrs = issue_metrics_table[:first_associated_with_milestone_at] @stage = :plan
@start_time_attrs = issue_metrics_table[:first_associated_with_milestone_at]
@end_time_attrs = [issue_metrics_table[:first_added_to_board_at], @end_time_attrs = [issue_metrics_table[:first_added_to_board_at],
issue_metrics_table[:first_mentioned_in_commit_at]] issue_metrics_table[:first_mentioned_in_commit_at]]
@projections = [mr_diff_table[:st_commits].as('commits'),
@projections = [mr_diff_table[:st_commits].as('commits'), issue_metrics_table[:first_mentioned_in_commit_at]]
issue_metrics_table[:first_mentioned_in_commit_at]]
super(*args)
end
class << self def custom_query(base_query)
def query(base_query) base_query.join(mr_diff_table).on(mr_diff_table[:merge_request_id].eq(mr_table[:id]))
base_query.join(mr_diff_table).on(mr_diff_table[:merge_request_id].eq(mr_table[:id])) end
end
private private
def serialize(event, query) def serialize(event)
st_commit = first_time_reference_commit(event.delete('commits'), event) st_commit = first_time_reference_commit(event.delete('commits'), event)
return unless st_commit return unless st_commit
serialize_commit(event, st_commit, query) serialize_commit(event, st_commit, query)
end end
def first_time_reference_commit(commits, event) def first_time_reference_commit(commits, event)
YAML.load(commits).find do |commit| YAML.load(commits).find do |commit|
next unless commit[:committed_date] && event['first_mentioned_in_commit_at'] next unless commit[:committed_date] && event['first_mentioned_in_commit_at']
commit[:committed_date].to_i == DateTime.parse(event['first_mentioned_in_commit_at'].to_s).to_i commit[:committed_date].to_i == DateTime.parse(event['first_mentioned_in_commit_at'].to_s).to_i
end
end end
end
def serialize_commit(event, st_commit, query) def serialize_commit(event, st_commit, query)
commit = Commit.new(Gitlab::Git::Commit.new(st_commit), @project) commit = Commit.new(Gitlab::Git::Commit.new(st_commit), @project)
AnalyticsCommitSerializer.new(project: query.project, total_time: event['total_time']).represent(commit).as_json AnalyticsCommitSerializer.new(project: @project, total_time: event['total_time']).represent(commit).as_json
end
end end
end end
end end
......
module Gitlab module Gitlab
module CycleAnalytics module CycleAnalytics
class ProductionEvent < BaseEvent class ProductionEvent < BaseEvent
@stage = :production def initialize(*args)
@start_time_attrs = issue_table[:created_at] @stage = :production
@start_time_attrs = issue_table[:created_at]
@end_time_attrs = mr_metrics_table[:first_deployed_to_production_at]
@projections = [issue_table[:title],
issue_table[:iid],
issue_table[:id],
issue_table[:created_at],
issue_table[:author_id]]
@end_time_attrs = mr_metrics_table[:first_deployed_to_production_at] super(*args)
end
@projections = [issue_table[:title], private
issue_table[:iid],
issue_table[:id],
issue_table[:created_at],
issue_table[:author_id]]
def self.serialize(event, query) def serialize(event)
event['author'] = User.find(event.delete('author_id')) event['author'] = User.find(event.delete('author_id'))
AnalyticsIssueSerializer.new(project: query.project).represent(event).as_json AnalyticsIssueSerializer.new(project: @project).represent(event).as_json
end
def has_permission?(id)
@options[:current_user].can?(:read_issue, Issue.find(id))
end end
end end
end end
......
module Gitlab module Gitlab
module CycleAnalytics module CycleAnalytics
class ReviewEvent < BaseEvent class ReviewEvent < BaseEvent
@stage = :review def initialize(*args)
@start_time_attrs = mr_table[:created_at] @stage = :review
@end_time_attrs = mr_metrics_table[:merged_at] @start_time_attrs = mr_table[:created_at]
@projections = [mr_table[:title], @end_time_attrs = mr_metrics_table[:merged_at]
mr_table[:iid], @projections = [mr_table[:title],
mr_table[:id], mr_table[:iid],
mr_table[:created_at], mr_table[:id],
mr_table[:state], mr_table[:created_at],
mr_table[:author_id]] mr_table[:state],
mr_table[:author_id]]
def self.serialize(event, query) super(*args)
end
def serialize(event)
event['author'] = User.find(event.delete('author_id')) event['author'] = User.find(event.delete('author_id'))
AnalyticsMergeRequestSerializer.new(project: query.project).represent(event).as_json AnalyticsMergeRequestSerializer.new(project: @project).represent(event).as_json
end
def has_permission?(id)
@options[:current_user].can?(:read_merge_request, MergeRequest.find(id))
end end
end end
end end
......
module Gitlab module Gitlab
module CycleAnalytics module CycleAnalytics
class StagingEvent < BaseEvent class StagingEvent < BaseEvent
@stage = :staging def initialize(*args)
@start_time_attrs = mr_metrics_table[:merged_at] @stage = :staging
@end_time_attrs = mr_metrics_table[:first_deployed_to_production_at] @start_time_attrs = mr_metrics_table[:merged_at]
@projections = [build_table[:id]] @end_time_attrs = mr_metrics_table[:first_deployed_to_production_at]
@order = build_table[:created_at] @projections = [build_table[:id]]
@order = build_table[:created_at]
def self.query(base_query) super(*args)
end
def custom_query(base_query)
base_query.join(build_table).on(mr_metrics_table[:pipeline_id].eq(build_table[:commit_id])) base_query.join(build_table).on(mr_metrics_table[:pipeline_id].eq(build_table[:commit_id]))
end end
def self.serialize(event, _query) private
def serialize(event)
build = ::Ci::Build.find(event['id']) build = ::Ci::Build.find(event['id'])
AnalyticsBuildSerializer.new.represent(build).as_json AnalyticsBuildSerializer.new.represent(build).as_json
......
module Gitlab module Gitlab
module CycleAnalytics module CycleAnalytics
class TestEvent < BaseEvent class TestEvent < BaseEvent
@stage = :test def initialize(*args)
@start_time_attrs = mr_metrics_table[:latest_build_started_at] @stage = :test
@end_time_attrs = mr_metrics_table[:latest_build_finished_at] @start_time_attrs = mr_metrics_table[:latest_build_started_at]
@projections = [build_table[:id]] @end_time_attrs = mr_metrics_table[:latest_build_finished_at]
@order = build_table[:created_at] @projections = [build_table[:id]]
@order = build_table[:created_at]
def self.query(base_query) super(*args)
end
def custom_query(base_query)
base_query.join(build_table).on(mr_metrics_table[:pipeline_id].eq(build_table[:commit_id])) base_query.join(build_table).on(mr_metrics_table[:pipeline_id].eq(build_table[:commit_id]))
end end
def self.serialize(event, _query) private
def serialize(event)
build = ::Ci::Build.find(event['id']) build = ::Ci::Build.find(event['id'])
AnalyticsBuildSerializer.new.represent(build).as_json AnalyticsBuildSerializer.new.represent(build).as_json
......
...@@ -6,7 +6,7 @@ describe Gitlab::CycleAnalytics::Events do ...@@ -6,7 +6,7 @@ describe Gitlab::CycleAnalytics::Events do
let(:user) { create(:user, :admin) } let(:user) { create(:user, :admin) }
let!(:context) { create(:issue, project: project, created_at: 2.days.ago) } let!(:context) { create(:issue, project: project, created_at: 2.days.ago) }
subject { described_class.new(project: project, options: { from: from_date }) } subject { described_class.new(project: project, options: { from: from_date, current_user: user }) }
before do before do
allow_any_instance_of(Gitlab::ReferenceExtractor).to receive(:issues).and_return([context]) allow_any_instance_of(Gitlab::ReferenceExtractor).to receive(:issues).and_return([context])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment