module PactBroker
Allow contracts to be accessed by name and configured/overridden for pf
The contract for the contract object in the publish contracts request
Formats a message string into application/problem+json format.
Builds the Hash that is passed into the Decorator as the ‘user_options`. It contains the request details, rack env, the (optional) title and anything else that is required by the decorator to render the resource (eg. the pacticipant that the versions belong to)
Decorates Dry::Validation::MessageSet Defaults to displaying validation errors, but the top level details may be overridden to display error responses for other HTTP statuses (eg. 409)
Decorates the individual validation error message Dry::Validation::Message
Formats a nested Hash of errors into the “old” Pact
Broker errors format TODO: delete this in favour of problem+json in the next major version
Pactflow notes: This decorator was added for Pactflow, but we needed to change it so much that there is a separate class in pact_broker_fork/lib/pactflow/api/decorators/extended_pact_decorator.rb now and this one isn’t used.
TODO remove this class
Formats a message string into application/problem+json format.
Formats a nested Hash of errors, or an Array of Strings, into the “old” Pact
Broker errors format TODO: delete this in favour of problem+json in the next major version
Allows the load-time configuration to be overridden on a per-request basis (for Pactflow)
Not exposed yet as we’d need to support administrator auth first
Logs the error Reports the error Generates and returns response headers and response body
Generates the response headers and body for use when there is a runtime error in the business logic (services and repositories) when executing a Webmachine
resource request. Obfuscates any exception messages that might expose vulnerablities in production. Uses the Accept header to determine whether to return application/problem+json or application/hal+json, for backwards compatibility. In the next major version of the Pact
Broker, all error responses should use problem+json, regardless of Accept headers.
Saves a block for execution after the HTTP response has been sent to the user. When the block is executed, it connects to the database before executing the code. This is good for doing things that might take a while and don’t have to be done before the response is sent, and don’t need retries (in which case, it might be better to use a SuckerPunch Job).
This leverages a feature of Puma which I’m not sure is meant to be public or not. There are serveral mentions of it on the internet, so I assume it’s ok to use it. Puma itself uses the rack.after_reply for http request logging.
github.com/search?q=repo%3Apuma%2Fpuma%20rack.after_reply&type=code
An array that provides the pagination details
Uses a Postgres advisory lock to ensure that a given block of code can only have ONE thread in excution at a time against a given database. When the database is not Postgres, the block will yield without any locks, allowing this class to be used safely with other database types, but without the locking functionality.
This is a wrapper around the actual implementation code in the Sequel
extension from github.com/yuryroot/sequel-pg_advisory_lock which was copied into this codebase and modified for usage in this codebase.
See www.postgresql.org/docs/16/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS for docs on lock types
Populate the newly created contract_data_updated_at date in the integrations table using the latest created_at date from the pact_publications or verifications tables.
Not required now we have the auto_detect_main_branch feature
Data migrations run every time the broker starts up, after the schema migrations. Their purpose is to ensure that data integrity is maintained during rolling migrations in architectures with multiple application instances running against the same database (eg. EC2 autoscaling group) where “old” data might be inserted by the application instance running the previous version of the code AFTER the schema migrations have been run on the first application instance with the new version of the code.
This class most accurately represents a PactPublication
The Wisper implementation of temporary listeners clears all listeners at the end of the block, rather the just the ones that were supplied in block. This implementation just clears the specified ones, allowing multiple temporary overlapping listeners.
Listens for events that happen in the Pact
Broker that are relevant to the Integrations
objects.
Same as PactBroker::Matrix::MatrixRow
except the data is sourced from the pact_publications table, and contains every pact publication, not just the latest publication for the consumer version. This is used when there is no “latestby” in the matrix query.
Represents the integration relationship between a consumer and a provider in the context of a matrix or can-i-deploy query. If the required flag is set, then one of the pacticipants specified in the matrix query is a consumer and it requires the provider to be already deployed. An integration would not be required if a provider was specified, and it had an integration with a consumer, but that consumer wasn’t deployed yet.
A Sequel
model used for identifying potential and required integrations between the versions described by the specified selectors and other applications. It is only meant to be used via the public dataset methods.
A “find only” repository for the PactBroker::Matrix::Integration
object. The PactBroker::Matrix::Integration
object is not a Sequel
Model like the PactBroker::Integrations::Integration
- it is built from the matrix data specifically for a given matrix query, and as well as the consumer/provider attributes, it also knows whether or not that particular depdency is required in the context of the specific matrix query. eg. a HTTP consumer will always require that a provider is deployed, but a provider can be deployed if the consumer does not exist in the given environment yet. The “integrations for selectors” query is used to work out what what integrations are involved for a can-i-deploy query.
The PactBroker::Matrix::MatrixRow
represents a row in the table that is created when the consumer versions are joined to the provider versions via the pacts and verifications tables, aka “The Matrix”. The difference between this class and the EveryRow class is that the EveryRow class includes results for overridden pact verisons and verifications (used only when there is no latestby set in the matrix query), where as the MatrixRow class only includes the latest pact for each consumer version, and the latest verification for each provider version.
The dataset methods used by both the MatrixRow and the EveryRow classes Requires the following methods to be defined on the model
- verification_dataset - select_pact_columns_with_aliases - select_all_columns_after_join
The instance methods
The dataset methods to be included in the MatrixRow::Verification dataset module and the EveryRow::Verification dataset module. Expects the method ‘select_verification_columns_with_aliases` to be defined on the class
A selector with the pacticipant id, name, version number, and version id set This is created from either specified or inferred data, based on the user’s query eg. can-i-deploy –pacticipant Foo –version 1 (this is a specified selector)
--to prod (this is used to create inferred selectors, one for each integrated pacticipant in that environment)
When an UnresolvedSelector specifies multiple application versions (eg. { tag: “prod” }) then a ResolvedSelector is created for every Version object found for the original selector.
Builds a PactBroker::Matrix::UnresolvedSelector
based on the given UnresolvedSelector, selector type, Pacticipant and Version objects, using the selector_ignorer to work out if the built ResolvedSelector should be marked as ignored or not.
Builds the array of ResolvedSelector objects using the ignore selectors, the specified selectors, and the inferred integrations.
The only reason why we need to resolve the ignore selectors is that we check in PactBroker::Matrix::DeploymentStatusSummary
whether or not the pacticipant or version they specify actually exist. We could actually have performed the ignore checks just using the name and version number.
Take the selectors and options provided by the user (eg. [{ pacticipant_name: “Foo”, pacticipant_version_number: “1” }], { to_environment: “prod” }) that use pacticipant/version/branch/environment names, and look up the IDs of all the objects, and return them as ResolvedSelector objects. For unresolved selectors that specify a collection of versions (eg. { branch: “main” }) a ResolvedSelector will be returned for every pacticipant version found. This will eventually be used in the can-i-deploy logic in PactBroker::Matrix::DeploymentStatusSummary
to work out if there are any missing verifications.
A head pact is the pact for the latest consumer version with the specified tag (ignoring later versions that might have the specified tag but no pact)
All of these pacts have the same underlying pact_version_sha (content) No point verifying them multiple times, so squash all the relevant info into one “verifiable pact”
This task is used to clean up old data in a Pact
Broker database to stop performance issues from slowing down responses when there is too much data. See docs.pact.io/pact_broker/administration/maintenance
require ‘pact_broker/tasks’
PactBroker::DB::DataMigrationTask.new
do | task |
require 'my_app/db' task.database_connection = MyApp::DB
end
require ‘pact_broker/tasks’
PactBroker::DB::MigrationTask.new
do | task |
require 'my_app/db' task.database_connection = MyApp::DB
end
require ‘pact_broker/tasks’
PactBroker::DB::VersionTask.new
do | task |
require 'my_app/db' task.database_connection = MyApp::DB
end
TODO handle 404 gracefully
Represents a non WIP, successful verification for a provider version with a tag.
The concept of “stale” (the pact used to be verified but then it changed and we haven’t got a new verification result yet) only really make sense if we’re trying to summarise the state of an integration or pseudo branch. Once we start showing multiple pacts for each integration (ie. the latest for each tag) then each pact version is either verified, or it’s not verified.
Represents the relationship between a webhook and the event and object that caused it to be triggered. eg a pact publication
Constants
- CONSUMER_VERSION_HEADER
- DO_NOT_ROLLBACK
- INTEGRATIONS_TABLES
- PACT_PARSING_OPTIONS
- VERSION
Public Class Methods
Source
# File lib/pact_broker/api.rb, line 28 def self.build_api(application_context = PactBroker::ApplicationContext.default_application_context) Webmachine.build_rack_api(application_context) do |app| app.routes do add(["trace", :*], Webmachine::Trace::TraceResource) unless ENV["RACK_ENV"] == "production" add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "versions"], Api::Resources::PactVersions, {resource_name: "pact_publications"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "versions", :consumer_version_number], Api::Resources::Pact, {resource_name: "pact_publication", deprecated: true} # Not the standard URL, but keep for backwards compatibility add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "tag", :tag], Api::Resources::TaggedPactVersions, {resource_name: "tagged_pact_publications"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch", :branch_name], Api::Resources::PactVersionsForBranch, {resource_name: "pact_publications_for_branch"} # Pacts add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number], Api::Resources::Pact, {resource_name: "pact_publication"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha], Api::Resources::PactVersion, {resource_name: "pact_publication"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "metadata", :metadata], Api::Resources::PactVersion, {resource_name: "pact_publication"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number, "previous-distinct"], Api::Resources::PreviousDistinctPactVersion, {resource_name: "previous_distinct_pact_version"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number, "diff", "previous-distinct"], Api::Resources::PactContentDiff, {resource_name: "previous_distinct_pact_version_diff"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number, "diff", "version", :comparison_consumer_version], Api::Resources::PactContentDiff, {resource_name: "pact_version_diff_by_consumer_version"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "diff", "pact-version", :comparison_pact_version_sha], Api::Resources::PactContentDiff, {resource_name: "pact_version_diff_by_pact_version_sha"} # Provider states add ["pacts", "provider", :provider_name, "provider-states"], Api::Resources::ProviderStates, { resource_name: "provider_states" } # Verifications add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "verification-results"], Api::Resources::Verifications, {resource_name: "verification_results"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "metadata", :metadata, "verification-results"], Api::Resources::Verifications, {resource_name: "verification_results"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number, "verification-results", "latest"], Api::Resources::LatestVerificationForPact, {resource_name: "latest_verification_results_for_pact_publication"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "verification-results", "latest"], Api::Resources::LatestVerificationForPact, {resource_name: "latest_verification_results_for_pact_version"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "verification-results", :verification_number], Api::Resources::Verification, {resource_name: "verification_result"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "metadata", :metadata, "verification-results", :verification_number], Api::Resources::Verification, {resource_name: "verification_result"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "pact-version", :pact_version_sha, "verification-results", :verification_number, "triggered-webhooks"], Api::Resources::VerificationTriggeredWebhooks, {resource_name: "verification_result_triggered_webhooks"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest", "verification-results","latest"], Api::Resources::LatestVerificationForLatestPact, {resource_name: "latest_verification_results_for_latest_pact_publication"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest", :tag, "verification-results","latest"], Api::Resources::LatestVerificationForLatestPact, {resource_name: "latest_verification_results_for_latest_tagged_pact_publication"} add ["verification-results", "consumer", :consumer_name, "version", :consumer_version_number,"latest"], Api::Resources::LatestVerificationsForConsumerVersion, {resource_name: "verification_results_for_consumer_version"} # Badges add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest", "badge"], Api::Resources::Badge, {resource_name: "latest_pact_badge"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest", :tag, "badge"], Api::Resources::Badge, {resource_name: "latest_tagged_pact_badge"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest-untagged", "badge"], Api::Resources::Badge, {resource_name: "latest_untagged_pact_badge", tag: :untagged} # Latest pacts add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest"], Api::Resources::LatestPact, {resource_name: "latest_pact_publication"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest", :tag], Api::Resources::LatestPact, {resource_name: "latest_tagged_pact_publication"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch", :branch_name, "latest"], Api::Resources::LatestPact, {resource_name: "latest_pact_publication_for_branch"} add ["pacts", "provider", :provider_name], Api::Resources::ProviderPacts, {resource_name: "provider_pact_publications"} add ["pacts", "provider", :provider_name, "tag", :tag], Api::Resources::ProviderPacts, {resource_name: "tagged_provider_pact_publications"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest-untagged"], Api::Resources::LatestPact, {resource_name: "latest_untagged_pact_publication", tag: :untagged} add ["pacts", "provider", :provider_name, "latest"], Api::Resources::LatestProviderPacts, {resource_name: "latest_provider_pact_publications"} add ["pacts", "provider", :provider_name, "latest", :tag], Api::Resources::LatestProviderPacts, {resource_name: "latest_tagged_provider_pact_publications"} add ["pacts", "latest"], Api::Resources::LatestPacts, {resource_name: "latest_pacts"} # Pacts for verification add ["pacts", "provider", :provider_name, "for-verification"], Api::Resources::ProviderPactsForVerification, {resource_name: "pacts_for_verification"} # Deprecated pact add ["pact", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number], Api::Resources::Pact, {resource_name: "pact_publication", deprecated: "true"} # Deprecate, singular /pact add ["pact", "provider", :provider_name, "consumer", :consumer_name, "latest"], Api::Resources::LatestPact, {resource_name: "latest_pact_publications", deprecated: "true"} # Pacticipants add ["pacticipants"], Api::Resources::Pacticipants, {resource_name: "pacticipants"} add ["pacticipants", "label", :label_name], PactBroker::Api::Resources::PacticipantsForLabel, {resource_name: "pacticipants_for_label"} add ["pacticipants", :pacticipant_name], Api::Resources::Pacticipant, {resource_name: "pacticipant"} add ["pacticipants", :pacticipant_name, "labels", :label_name], Api::Resources::Label, {resource_name: "pacticipant_label"} # Labels add ["labels"], Api::Resources::Labels, {resource_name: "labels"} # Versions add ["pacticipants", :pacticipant_name, "versions"], Api::Resources::Versions, {resource_name: "pacticipant_versions"} add ["pacticipants", :pacticipant_name, "branches", :branch_name, "versions"], Api::Resources::BranchVersions, {resource_name: "pacticipant_branch_versions"} add ["pacticipants", :pacticipant_name, "versions", :pacticipant_version_number], Api::Resources::Version, {resource_name: "pacticipant_version"} add ["pacticipants", :pacticipant_name, "latest-version", :tag], Api::Resources::LatestVersion, {resource_name: "latest_tagged_pacticipant_version"} add ["pacticipants", :pacticipant_name, "latest-version", :tag, "can-i-deploy", "to", :to], Api::Resources::CanIDeployPacticipantVersionByTagToTag, { resource_name: "can_i_deploy_latest_tagged_version_to_tag" } add ["pacticipants", :pacticipant_name, "latest-version", :tag, "can-i-deploy", "to", :to, "badge"], Api::Resources::CanIDeployPacticipantVersionByTagToTagBadge, { resource_name: "can_i_deploy_latest_tagged_version_to_tag_badge" } add ["pacticipants", :pacticipant_name, "main-branch", "can-i-merge", "badge"], Api::Resources::CanIMergeBadge, { resource_name: "can_i_merge_badge" } add ["pacticipants", :pacticipant_name, "latest-version"], Api::Resources::LatestVersion, {resource_name: "latest_pacticipant_version"} add ["pacticipants", :pacticipant_name, "versions", :pacticipant_version_number, "tags", :tag_name], Api::Resources::Tag, {resource_name: "pacticipant_version_tag"} add ["pacticipants", :pacticipant_name, "branches"], Api::Resources::PacticipantBranches, {resource_name: "pacticipant_branches"} add ["pacticipants", :pacticipant_name, "branches", :branch_name], Api::Resources::Branch, { resource_name: "branch" } add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version"], Api::Resources::LatestVersion, { resource_name: "latest_pacticipant_version_for_branch" } add ["pacticipants", :pacticipant_name, "branches", :branch_name, "versions", :version_number], Api::Resources::BranchVersion, { resource_name: "branch_version" } add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version", "can-i-deploy", "to-environment", :environment_name], Api::Resources::CanIDeployPacticipantVersionByBranchToEnvironment, { resource_name: "can_i_deploy_latest_branch_version_to_environment" } add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version", "can-i-deploy", "to-environment", :environment_name, "badge"], Api::Resources::CanIDeployPacticipantVersionByBranchToEnvironmentBadge, { resource_name: "can_i_deploy_latest_branch_version_to_environment_badge" } # Webhooks add ["webhooks", "provider", :provider_name, "consumer", :consumer_name ], Api::Resources::PacticipantWebhooks, {resource_name: "pacticipant_webhooks"} add ["webhooks", "provider", :provider_name], Api::Resources::PacticipantWebhooks, {resource_name: "provider_webhooks"} add ["webhooks", "consumer", :consumer_name], Api::Resources::PacticipantWebhooks, {resource_name: "consumer_webhooks"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "webhooks"], Api::Resources::PactWebhooks, {resource_name: "pact_webhooks"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "webhooks", "status"], Api::Resources::PactWebhooksStatus, {resource_name: "pact_webhooks_status"} add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "version", :consumer_version_number, "triggered-webhooks"], Api::Resources::PactTriggeredWebhooks, {resource_name: "pact_triggered_webhooks"} add ["webhooks", "execute" ], Api::Resources::WebhookExecution, {resource_name: "execute_unsaved_webhook"} add ["webhooks", :uuid ], Api::Resources::Webhook, {resource_name: "webhook"} add ["triggered-webhooks", :uuid, "logs" ], Api::Resources::TriggeredWebhookLogs, { resource_name: "triggered_webhook_logs" } add ["webhooks", :uuid, "execute" ], Api::Resources::WebhookExecution, {resource_name: "execute_webhook"} add ["webhooks"], Api::Resources::AllWebhooks, {resource_name: "webhooks"} add ["relationships"], Api::Resources::Relationships, {resource_name: "relationships"} add ["groups", :pacticipant_name], Api::Resources::Group, {resource_name: "group"} # matrix add ["matrix", "provider", :provider_name, "consumer", :consumer_name], Api::Resources::MatrixForConsumerAndProvider, {resource_name: "matrix_consumer_provider"} add ["matrix", "provider", :provider_name, "latest", :provider_tag, "consumer", :consumer_name, "latest", :tag, "badge"], Api::Resources::MatrixBadge, {resource_name: "matrix_tag_badge"} add ["matrix"], Api::Resources::Matrix, {resource_name: "matrix"} add ["can-i-deploy"], Api::Resources::CanIDeploy, {resource_name: "can_i_deploy"} add ["dashboard"], Api::Resources::Dashboard, {resource_name: "dashboard"} add ["dashboard", "provider", :provider_name, "consumer", :consumer_name ], Api::Resources::Dashboard, {resource_name: "integration_dashboard"} add ["test","error"], Api::Resources::ErrorTest, {resource_name: "error_test"} add ["contracts", "publish"], Api::Resources::PublishContracts, { resource_name: "publish_contracts" } add ["environments"], Api::Resources::Environments, { resource_name: "environments" } add ["environments", :environment_uuid], Api::Resources::Environment, { resource_name: "environment" } add ["environments", :environment_uuid, "deployed-versions", "currently-deployed"], Api::Resources::CurrentlyDeployedVersionsForEnvironment, { resource_name: "environment_currently_deployed_deployed_versions" } add ["environments", :environment_uuid, "released-versions", "currently-supported"], Api::Resources::CurrentlySupportedVersionsForEnvironment, { resource_name: "environment_currently_supported_released_versions" } add ["pacticipants", :pacticipant_name, "versions", :pacticipant_version_number, "deployed-versions", "environment", :environment_uuid], Api::Resources::DeployedVersionsForVersionAndEnvironment, { resource_name: "deployed_versions_for_version_and_environment" } add ["pacticipants", :pacticipant_name, "versions", :pacticipant_version_number, "released-versions", "environment", :environment_uuid], Api::Resources::ReleasedVersionsForVersionAndEnvironment, { resource_name: "released_versions_for_version_and_environment" } add ["released-versions", :uuid], Api::Resources::ReleasedVersion, { resource_name: "released_version" } add ["deployed-versions", :uuid], Api::Resources::DeployedVersion, { resource_name: "deployed_version" } add ["integrations"], Api::Resources::Integrations, {resource_name: "integrations"} add ["integrations", "provider", :provider_name, "consumer", :consumer_name], Api::Resources::Integration, {resource_name: "integration"} add ["metrics"], Api::Resources::Metrics, {resource_name: "metrics"} add [], Api::Resources::Index, {resource_name: "index"} add ["pacticipants", :pacticipant_name, "tags", :tag_name, "versions"], Api::Resources::TagVersions, {resource_name: "pacticipant_tag_versions"} end end end
rubocop: disable Metrics/MethodLength
Source
# File lib/pact_broker/configuration.rb, line 10 def self.configuration RequestStore.store[:pact_broker_configuration] ||= Configuration.default_configuration end
Source
# File lib/pact_broker/initializers/database_connection.rb, line 76 def self.configure_connection(connection, connection_validation_timeout, enable_caller_logging) connection.extension(:connection_validator) connection.extension(:caller_logging) if enable_caller_logging connection.pool.connection_validation_timeout = connection_validation_timeout if connection_validation_timeout connection end
Sequel
by default does not test connections in its connection pool before handing them to a client. To enable connection testing you need to load the “connection_validator” extension like below. The connection validator extension is configurable, by default it only checks connections once per hour:
sequel.rubyforge.org/rdoc-plugins/files/lib/sequel/extensions/connection_validator_rb.html
A gotcha here is that it is not enough to enable the “connection_validator” extension, we also need to specify that we want to use the threaded connection pool, as noted in the documentation for the extension.
-1 means that connections will be validated every time, which avoids errors when databases are restarted and connections are killed. This has a performance penalty, so consider increasing this timeout if building a frequently accessed service.
Source
# File lib/pact_broker/initializers/database_connection.rb, line 50 def self.configure_logger(sequel_config, logger) if sequel_config[:sql_log_level] == :none sequel_config.delete(:sql_log_level) elsif logger sequel_config[:logger] = PactBroker::DB::LogQuietener.new(logger) end end
Source
# File lib/pact_broker/initializers/database_connection.rb, line 6 def self.create_database_connection(config, logger = nil) logger&.info("Connecting to database:", config.merge(password: "*****")) sequel_config = config.dup max_retries = sequel_config.delete(:connect_max_retries) || 0 connection_validation_timeout = config.delete(:connection_validation_timeout) enable_caller_logging = config.delete(:enable_caller_logging) configure_logger(sequel_config, logger) create_sqlite_database_dir(config) connection = with_retries(max_retries, logger) do Sequel.connect(sequel_config) end logger&.info "Connected to database #{sequel_config[:database]}" configure_connection(connection, connection_validation_timeout, enable_caller_logging) end
Source
# File lib/pact_broker/initializers/database_connection.rb, line 43 def self.create_sqlite_database_dir(config) if config[:adapter] == "sqlite" && config[:database] && !File.exist?(File.dirname(config[:database])) logger&.info "Creating directory #{File.expand_path(File.dirname(config[:database]))} for Sqlite database" FileUtils.mkdir_p(File.dirname(config[:database])) end end
Source
# File lib/pact_broker/feature_toggle.rb, line 22 def self.feature_enabled?(feature, ignore_env = false) FeatureToggle.enabled?(feature, ignore_env) end
Source
# File lib/pact_broker/policies.rb, line 46 def self.policy!(*args) PactBroker.configuration.policy_builder.call(*args) end
Source
# File lib/pact_broker/policies.rb, line 50 def self.policy_scope!(*args) PactBroker.configuration.policy_scope_builder.call(*args) end
Source
# File lib/pact_broker/project_root.rb, line 4 def self.project_root @project_root ||= Pathname.new(File.expand_path("../../../",__FILE__)).freeze end
Source
# File lib/pact_broker/configuration.rb, line 19 def self.reset_configuration RequestStore.store[:pact_broker_configuration] = Configuration.default_configuration end
@private, for testing only
Source
# File lib/pact_broker/api.rb, line 166 def self.routes require "webmachine/describe_routes" @routes ||= Webmachine::DescribeRoutes.call([API.application]) end
Source
# File lib/pact_broker/configuration.rb, line 14 def self.set_configuration(configuration) RequestStore.store[:pact_broker_configuration] = configuration end
Source
# File lib/pact_broker/initializers/database_connection.rb, line 25 def self.with_retries(max_retries, logger) tries = 0 max_tries = max_retries + 1 wait = 3 begin yield rescue StandardError => e if (tries += 1) < max_tries logger&.info "Error connecting to database (#{e.class}). Waiting #{wait} seconds and trying again. #{max_tries-tries} tries to go." sleep wait retry else raise e end end end