class PactBroker::Index::Service

Constants

DEFAULT_PAGE_NUMBER
DEFAULT_PAGE_SIZE

Public Class Methods

consumer_version_tags(pact_publication, tags_option) click to toggle source

rubocop: enable Metrics/CyclomaticComplexity

# File lib/pact_broker/index/service.rb, line 126
def self.consumer_version_tags(pact_publication, tags_option)
  if tags_option == true
    pact_publication.head_pact_tags
  elsif tags_option.is_a?(Array)
    pact_publication.head_pact_tags.select{ |tag| tags_option.include?(tag.name)}
  else
    []
  end
end
db() click to toggle source
# File lib/pact_broker/index/service.rb, line 171
def self.db
  PactBroker::Pacts::PactPublication.db
end
find_all_index_items() click to toggle source
# File lib/pact_broker/index/service.rb, line 27
def self.find_all_index_items
  # Is there a better way to do this? Setting a page_size of nil or -1 doesn't work
  # If we get to 100000000000 index items, we're probably going to have bigger issues...
  find_index_items(page_number: 1, page_size: 100000000000)
end
find_index_items(options = {}) click to toggle source

rubocop: disable Metrics/CyclomaticComplexity rubocop: disable Metrics/MethodLength

# File lib/pact_broker/index/service.rb, line 61
def self.find_index_items options = {}
  latest_verifications_for_cv_tags = latest_verifications_for_consumer_version_tags(options)
  latest_pp_ids = latest_pact_publication_ids

  # We only need to know if a webhook exists for an integration, not what its properties are
  webhooks = PactBroker::Webhooks::Webhook.select(:consumer_id, :provider_id).distinct.all

  pact_publication_query = head_pact_publications(options)
  pagination_record_count = pact_publication_query.pagination_record_count

  pact_publications = pact_publication_query
    .eager(:consumer)
    .eager(:provider)
    .eager(pact_version: { latest_verification: { provider_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }, :branch_heads, { tags: :head_tag } ] } })
    .eager(integration: [{latest_verification: :provider_version}, :latest_triggered_webhooks])
    .eager(consumer_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }, :branch_heads, { tags: :head_tag }])
    .eager(:head_pact_publications_for_tags)

  index_items = pact_publications.all.collect do | pact_publication |
    is_overall_latest_for_integration = latest_pp_ids.include?(pact_publication.id)

    latest_verification = latest_verification_for_pseudo_branch(pact_publication, is_overall_latest_for_integration, latest_verifications_for_cv_tags, options[:tags], options)
    webhook = webhooks.find{ |wh| wh.is_for?(pact_publication.integration) }

    PactBroker::Domain::IndexItem.create(
      pact_publication.consumer,
      pact_publication.provider,
      pact_publication.consumer_version,
      pact_publication.to_domain_lightweight,
      is_overall_latest_for_integration,
      latest_verification,
      webhook ? [webhook]: [],
      pact_publication.integration.latest_triggered_webhooks,
      consumer_version_tags(pact_publication, options[:tags]).sort_by(&:created_at).collect(&:name),
      options[:tags] && latest_verification ? latest_verification.provider_version.tags.select(&:latest_for_pacticipant?).sort_by(&:created_at) : [],
      pact_publication.latest_for_branch?
    )
  end.sort

  Page.new(index_items, pagination_record_count)
end
find_index_items_for_api(consumer_name: nil, provider_name: nil, page_number: nil, page_size: nil, **_ignored) click to toggle source
# File lib/pact_broker/index/service.rb, line 136
def self.find_index_items_for_api(consumer_name: nil, provider_name: nil, page_number: nil, page_size: nil, **_ignored)
  latest_pp_ids = latest_pact_publication_ids
  pact_publications = head_pact_publications(consumer_name: consumer_name, provider_name: provider_name, tags: true, page_number: page_number, page_size: page_size)
    .eager(:consumer)
    .eager(:provider)
    .eager(pact_version: { latest_verification: { provider_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }, { branch_heads: :branch_version }, { tags: :head_tag }]} })
    .eager(consumer_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }, { branch_heads: :branch_version }, { tags: :head_tag }])
    .eager(:head_pact_publications_for_tags)

  pact_publications.all.collect do | pact_publication |
    is_overall_latest_for_integration = latest_pp_ids.include?(pact_publication.id)

    PactBroker::Domain::IndexItem.create(
      pact_publication.consumer,
      pact_publication.provider,
      pact_publication.consumer_version,
      pact_publication.to_domain_lightweight,
      is_overall_latest_for_integration,
      pact_publication.latest_verification,
      [],
      [],
      pact_publication.head_pact_tags.sort_by(&:created_at).collect(&:name),
      pact_publication.latest_verification ? pact_publication.latest_verification.provider_version.tags.select(&:latest_for_pacticipant?).sort_by(&:created_at) : []
    )
  end.sort
end
head_pact_publications(options = {}) click to toggle source
# File lib/pact_broker/index/service.rb, line 175
def self.head_pact_publications(options = {})
  base = base_query(options)

  if options[:search]
    pacticipant_ids = pact_pacticipant_ids_by_name(options[:search])
    base = base.where(Sequel.|(
      { Sequel[:pact_publications][:consumer_id] => pacticipant_ids },
      { Sequel[:pact_publications][:provider_id] => pacticipant_ids }
    ))

    # Return early if there is no pacticipant matches the input name
    return base.paginate(options[:page_number] || DEFAULT_PAGE_NUMBER, options[:page_size] || DEFAULT_PAGE_SIZE) if pacticipant_ids.blank?
  end

  ids_query = if options[:view]
                pact_publications_by_view(base, options)
              else
                query_pact_publication_ids_by_tags(base, options[:tags])
              end

  select_columns_and_order(ids_query, options)
end
latest_pact_publication_ids() click to toggle source
# File lib/pact_broker/index/service.rb, line 167
def self.latest_pact_publication_ids
  PactBroker::Pacts::PactPublication.select(Sequel[:pact_publications][:id]).overall_latest.collect(&:id)
end
latest_pact_publications() click to toggle source
# File lib/pact_broker/index/service.rb, line 163
def self.latest_pact_publications
  PactBroker::Pacts::PactPublication.overall_latest
end
latest_verification_for_pseudo_branch(pact_publication, is_overall_latest, latest_verifications_for_cv_tags, tags_option, options) click to toggle source

Worst. Code. Ever. This needs a big rethink. TODO environments view rubocop: disable Metrics/CyclomaticComplexity

# File lib/pact_broker/index/service.rb, line 109
def self.latest_verification_for_pseudo_branch(pact_publication, is_overall_latest, latest_verifications_for_cv_tags, tags_option, options)
  if options[:view] == "branch" || (options[:view] == "all" && pact_publication.consumer_version.branch_heads.any?)
    pact_publication.latest_verification || pact_publication.latest_verification_for_consumer_branches
  elsif tags_option == true
    latest_verifications_for_cv_tags
      .select{ | v | v.consumer_id == pact_publication.consumer_id && v.provider_id == pact_publication.provider_id && pact_publication.head_pact_tags.collect(&:name).include?(v.consumer_version_tag_name) }
      .sort{ |v1, v2| v1.id <=> v2.id }.last || (is_overall_latest ? pact_publication.integration.latest_verification : nil)
  elsif tags_option.is_a?(Array)
    latest_verifications_for_cv_tags
    .select{ | v | v.consumer_id == pact_publication.consumer_id && v.provider_id == pact_publication.provider_id && pact_publication.head_pact_tags.collect(&:name).include?(v.consumer_version_tag_name) && tags_option.include?(v.consumer_version_tag_name) }
    .sort{ |v1, v2| v1.id <=> v2.id }.last  || (is_overall_latest ? pact_publication.integration.latest_verification : nil)
  else
    pact_publication.integration.latest_verification
  end
end
latest_verifications_for_consumer_version_tags(options) click to toggle source

eager loading the tag stuff doesn't seem to make it quicker

# File lib/pact_broker/index/service.rb, line 213
def self.latest_verifications_for_consumer_version_tags(options)
  # server side rendered index page with tags[]=a&tags=[]b
  if options[:tags].is_a?(Array)
    PactBroker::Verifications::LatestVerificationForConsumerVersionTag
      .eager(:provider_version)
      .where(consumer_version_tag_name: options[:tags])
      .all
  elsif options[:tags] # server side rendered index page with tags=true
    PactBroker::Verifications::LatestVerificationForConsumerVersionTag
      .eager(provider_version: [{ current_deployed_versions: :environment }, { current_supported_released_versions: :environment }])
      .all
  else
    nil # should not be used
  end
end
pact_publication_scope() click to toggle source

This method provides data for both the OSS server side rendered index (with and without tags) and the Pactflow UI. It really needs to be broken into to separate methods, as it's getting too messy supporting both

# File lib/pact_broker/index/service.rb, line 23
def self.pact_publication_scope
  PactBroker.policy_scope!(PactBroker::Pacts::PactPublication)
end
pact_publications_by_view(query, options) click to toggle source
# File lib/pact_broker/index/service.rb, line 198
def self.pact_publications_by_view(query, options)
  case options[:view]
  when "branch" then query.latest_by_consumer_branch
  when "tag" then query.latest_by_consumer_tag
  when "environment" then query.in_environments
  else
    query
      .overall_latest
      .union(query.latest_by_consumer_branch)
      .union(query.latest_by_consumer_tag)
      .union(query.in_environments)
  end
end
smart_default_view(consumer_name, provider_name) click to toggle source
# File lib/pact_broker/index/service.rb, line 33
def self.smart_default_view(consumer_name, provider_name)
  consumer = pacticipant_repository.find_by_name(consumer_name)
  provider = pacticipant_repository.find_by_name(provider_name)
  if consumer && provider
    pact_publications_with_branches = PactBroker::Pacts::PactPublication
                                      .for_consumer_name(consumer_name)
                                      .for_provider_name(provider_name)
                                      .join_consumer_branch_versions

    pact_publication_with_tags =   PactBroker::Pacts::PactPublication
      .for_consumer_name(consumer_name)
      .for_provider_name(provider_name)
      .join_consumer_version_tags

    if pact_publications_with_branches.any?
      "branch"
    elsif pact_publication_with_tags.any?
      "tag"
    else
      "all"
    end
  else
    nil
  end
end

Private Class Methods

base_query(options) click to toggle source
# File lib/pact_broker/index/service.rb, line 236
def self.base_query(options)
  query = PactBroker::Pacts::PactPublication.select(Sequel[:pact_publications][:id])

  if options[:consumer_name]
    consumer = pacticipant_repository.find_by_name!(options[:consumer_name])
    query = query.for_consumer(consumer)
  end

  if options[:provider_name]
    provider = pacticipant_repository.find_by_name!(options[:provider_name])
    query = query.for_provider(provider)
  end

  query
end
pact_pacticipant_ids_by_name(pacticipant_name) click to toggle source
# File lib/pact_broker/index/service.rb, line 253
def self.pact_pacticipant_ids_by_name(pacticipant_name)
  pacticipant_repository.search_by_name(pacticipant_name).collect(&:id)
end
query_pact_publication_ids_by_tags(base, tags) click to toggle source
# File lib/pact_broker/index/service.rb, line 229
def self.query_pact_publication_ids_by_tags(base, tags)
  latest = base.overall_latest
  return latest.union(base.latest_for_consumer_tag(tags)) if tags.is_a?(Array)
  return latest.union(base.latest_by_consumer_tag).union(base.for_environment(nil)) if tags
  latest
end
select_columns_and_order(ids_query, options) click to toggle source
# File lib/pact_broker/index/service.rb, line 257
def self.select_columns_and_order(ids_query, options)
  query = PactBroker::Pacts::PactPublication
            .select_all_qualified
            .where(Sequel[:pact_publications][:id] => ids_query)
            .join_consumers(:consumers)
            .join_providers(:providers)


  order_columns = [
    Sequel.asc(Sequel.function(:lower, Sequel[:consumers][:name])),
    Sequel.desc(Sequel[:pact_publications][:consumer_version_order]),
    Sequel.asc(Sequel.function(:lower, Sequel[:providers][:name]))
  ]

  pact_number = options[:page_number] || DEFAULT_PAGE_NUMBER
  page_size = options[:page_size] || DEFAULT_PAGE_SIZE

  query.order(*order_columns).paginate(pact_number, page_size)
end