module PactBroker::Webhooks::TriggerService

Constants

RESOURCE_CREATION
USER

Public Instance Methods

create_triggered_webhooks_for_event(pact, verification, event_name, event_context) click to toggle source

the main entry point

# File lib/pact_broker/webhooks/trigger_service.rb, line 17
def create_triggered_webhooks_for_event pact, verification, event_name, event_context
  webhooks = webhook_repository.find_webhooks_to_trigger(consumer: pact.consumer, provider: pact.provider, event_name: event_name)

  if webhooks.any?
    create_triggered_webhooks_for_webhooks(webhooks, pact, verification, event_name, event_context.merge(event_name: event_name))
  else
    []
  end
end
execute_triggered_webhook_now(triggered_webhook, webhook_execution_configuration_hash) click to toggle source
# File lib/pact_broker/webhooks/trigger_service.rb, line 43
def execute_triggered_webhook_now triggered_webhook, webhook_execution_configuration_hash
  webhook_execution_result = triggered_webhook.execute(webhook_execution_configuration_hash)
  webhook_repository.create_execution(triggered_webhook, webhook_execution_result)
  webhook_execution_result
end
expand_events_for_required_verifications(event_name, pact, event_contexts) click to toggle source
# File lib/pact_broker/webhooks/trigger_service.rb, line 132
def expand_events_for_required_verifications(event_name, pact, event_contexts)
  if event_name == PactBroker::Webhooks::WebhookEvent::CONTRACT_REQUIRING_VERIFICATION_PUBLISHED
    required_verifications = verification_service.calculate_required_verifications_for_pact(pact)
    event_contexts.flat_map do | event_context |
      required_verifications.collect do | required_verification |
        event_context.merge(
          provider_version_number: required_verification.provider_version.number,
          provider_version_branch: provider_version_branch_for_required_verification(required_verification, ),
          provider_version_descriptions: required_verification.provider_version_descriptions.uniq
        )
      end
    end
  else
    event_contexts
  end
end
next_uuid() click to toggle source
# File lib/pact_broker/webhooks/trigger_service.rb, line 27
def next_uuid
  SecureRandom.uuid
end
provider_version_branch_for_required_verification(required_verification) click to toggle source
# File lib/pact_broker/webhooks/trigger_service.rb, line 149
def provider_version_branch_for_required_verification(required_verification)
  required_verification.provider_version_selectors.find(&:latest_for_main_branch?)&.resolved_branch_name || required_verification.provider_version.branch_versions.last&.branch_name
end
schedule_webhooks(triggered_webhooks, options) click to toggle source
# File lib/pact_broker/webhooks/trigger_service.rb, line 49
def schedule_webhooks(triggered_webhooks, options)
  triggered_webhooks.each_with_index do | triggered_webhook, i |
    logger.info "Scheduling job for webhook with uuid #{triggered_webhook.webhook.uuid}, context: #{triggered_webhook.event_context}"
    logger.debug "Schedule webhook with options #{options}"

    job_data = { triggered_webhook: triggered_webhook }.deep_merge(options)
    begin
      # Delay slightly to make sure the request transaction has finished before we execute the webhook
      Job.perform_in(5 + (i * 3), job_data)
    rescue StandardError => e
      logger.warn("Error scheduling webhook execution for webhook with uuid #{triggered_webhook&.webhook&.uuid}", e)
      nil
    end
  end
end
test_execution(webhook, event_context, execution_configuration) click to toggle source
# File lib/pact_broker/webhooks/trigger_service.rb, line 31
def test_execution webhook, event_context, execution_configuration
  merged_options = execution_configuration.with_failure_log_message("Webhook execution failed").to_hash

  verification = nil
  if webhook.trigger_on_provider_verification_published?
    verification = verification_service.search_for_latest(webhook.consumer_name, webhook.provider_name) || PactBroker::Verifications::PlaceholderVerification.new
  end

  pact = pact_service.search_for_latest_pact(consumer_name: webhook.consumer_name, provider_name: webhook.provider_name) || PactBroker::Pacts::PlaceholderPact.new
  webhook.execute(pact, verification, event_context.merge(event_name: "test"), merged_options)
end

Private Instance Methods

create_triggered_webhooks_for_webhooks(webhooks, pact, verification, event_name, event_context) click to toggle source
# File lib/pact_broker/webhooks/trigger_service.rb, line 65
def create_triggered_webhooks_for_webhooks webhooks, pact, verification, event_name, event_context
  webhooks.flat_map do | webhook |
    expanded_event_contexts = expand_events_for_currently_deployed_environments(webhook, pact, event_context)
    expanded_event_contexts = expand_events_for_required_verifications(event_name, pact, expanded_event_contexts)
    expanded_event_contexts = expanded_event_contexts.flat_map { | ec | expand_events_for_verification_of_multiple_selected_pacts(ec) }

    expanded_event_contexts.collect do | expanded_event_context |
      pact_for_triggered_webhook = verification ? find_pact_for_verification_triggered_webhook(pact, expanded_event_context) : pact
      webhook_repository.create_triggered_webhook(next_uuid, webhook, pact_for_triggered_webhook, verification, RESOURCE_CREATION, event_name, expanded_event_context)
    end
  end
end
expand_events_for_currently_deployed_environments(webhook, pact, event_context) click to toggle source
# File lib/pact_broker/webhooks/trigger_service.rb, line 107
def expand_events_for_currently_deployed_environments(webhook, pact, event_context)
  if PactBroker.feature_enabled?(:expand_currently_deployed_provider_versions) && webhook.expand_currently_deployed_provider_versions?
    deployed_version_service.find_currently_deployed_versions_for_pacticipant(pact.provider).collect(&:version_number).uniq.collect do | version_number |
      event_context.merge(currently_deployed_provider_version_number: version_number)
    end
  else
    [event_context]
  end
end
expand_events_for_verification_of_multiple_selected_pacts(event_context) click to toggle source

Now that we de-duplicate the pact contents when verifying though the ‘pacts for verification’ API, we no longer get a webhook triggered for the verification results publication of each indiviual consumer version tag, meaning that only the most recent commit will get the updated verification status. To fix this, each URL of the pacts returned by the ‘pacts for verification’ API now contains the relevant selectors in the metadata, so that when the verification results are published, we can parse that metadata, and trigger one webhook for each consumer version like we used to. Actually, we used to trigger one webhook per tag, but given that the most likely use of the verification published webhook is for reporting git statuses, it makes more sense to trigger per consumer version number (ie. commit).

# File lib/pact_broker/webhooks/trigger_service.rb, line 96
def expand_events_for_verification_of_multiple_selected_pacts(event_context)
  if event_context[:consumer_version_selectors].is_a?(Array)
    event_context[:consumer_version_selectors]
      .group_by{ | selector | selector[:consumer_version_number] }
      .collect { | consumer_version_number, selectors | merge_consumer_version_selectors(consumer_version_number, selectors, event_context.without(:consumer_version_selectors)) }
  else
    [event_context]
  end
end
find_pact_for_verification_triggered_webhook(pact, reconstituted_event_context) click to toggle source
# File lib/pact_broker/webhooks/trigger_service.rb, line 118
def find_pact_for_verification_triggered_webhook(pact, reconstituted_event_context)
  if reconstituted_event_context[:consumer_version_number]
    find_pact_params = {
      consumer_name: pact.consumer_name,
      provider_name: pact.provider_name,
      consumer_version_number: reconstituted_event_context[:consumer_version_number]
    }
    pact_service.find_pact(find_pact_params) || pact
  else
    pact
  end
end
merge_consumer_version_selectors(consumer_version_number, selectors, event_context) click to toggle source
# File lib/pact_broker/webhooks/trigger_service.rb, line 79
def merge_consumer_version_selectors(consumer_version_number, selectors, event_context)
  event_context.merge(
    consumer_version_number: consumer_version_number,
    consumer_version_tags: selectors.collect{ | selector | selector[:tag] }.compact.uniq
  )
end