diff --git a/lib/pact_broker/api.rb b/lib/pact_broker/api.rb index a28444eee..57d98969d 100644 --- a/lib/pact_broker/api.rb +++ b/lib/pact_broker/api.rb @@ -91,6 +91,7 @@ module PactBroker 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"} end end diff --git a/lib/pact_broker/api/resources/index.rb b/lib/pact_broker/api/resources/index.rb index 0d6089102..126175b7e 100644 --- a/lib/pact_broker/api/resources/index.rb +++ b/lib/pact_broker/api/resources/index.rb @@ -106,6 +106,11 @@ def links title: "Get, create or delete a tag for a pacticipant version", templated: true }, + 'pb:metrics' => + { + href: base_url + '/metrics', + title: "Get Pact Broker metrics", + }, 'beta:pending-provider-pacts' => { href: base_url + '/pacts/provider/{provider}/pending', diff --git a/lib/pact_broker/api/resources/metrics.rb b/lib/pact_broker/api/resources/metrics.rb new file mode 100644 index 000000000..59e97f580 --- /dev/null +++ b/lib/pact_broker/api/resources/metrics.rb @@ -0,0 +1,21 @@ +require 'pact_broker/api/resources/base_resource' + +module PactBroker + module Api + module Resources + class Metrics < BaseResource + def content_types_provided + [["application/hal+json", :to_json]] + end + + def allowed_methods + ["GET", "OPTIONS"] + end + + def to_json + metrics_service.metrics.to_json + end + end + end + end +end diff --git a/lib/pact_broker/metrics/service.rb b/lib/pact_broker/metrics/service.rb new file mode 100644 index 000000000..c3cf68fb6 --- /dev/null +++ b/lib/pact_broker/metrics/service.rb @@ -0,0 +1,56 @@ +require 'pact_broker/pacts/pact_publication' +require 'pact_broker/pacts/pact_version' +require 'pact_broker/domain/pacticipant' +require 'pact_broker/integrations/integration' +require 'pact_broker/domain/verification' +require 'pact_broker/domain/version' +require 'pact_broker/api/decorators/format_date_time' +require 'pact_broker/webhooks/webhook' +require 'pact_broker/webhooks/triggered_webhook' +require 'pact_broker/webhooks/execution' + +module PactBroker + module Metrics + module Service + include PactBroker::Api::Decorators::FormatDateTime + + extend self + + def metrics + { + pacticipants: { + count: PactBroker::Domain::Pacticipant.count + }, + integrations: { + count: PactBroker::Integrations::Integration.count + }, + pactPublications: { + count: PactBroker::Pacts::PactPublication.count, + first: format_date_time(PactBroker::Pacts::PactPublication.order(:id).first&.created_at), + last: format_date_time(PactBroker::Pacts::PactPublication.order(:id).last&.created_at) + }, + pactVersions: { + count: PactBroker::Pacts::PactVersion.count + }, + verificationResults: { + count: PactBroker::Domain::Verification.count, + first: format_date_time(PactBroker::Domain::Verification.order(:id).first.created_at), + last: format_date_time(PactBroker::Domain::Verification.order(:id).last.created_at) + }, + pacticipantVersions: { + count: PactBroker::Domain::Version.count + }, + webhooks: { + count: PactBroker::Webhooks::Webhook.count + }, + triggeredWebhooks: { + count: PactBroker::Webhooks::TriggeredWebhook.count + }, + webhookExecutions: { + count: PactBroker::Webhooks::Execution.count + } + } + end + end + end +end diff --git a/lib/pact_broker/services.rb b/lib/pact_broker/services.rb index 8a08065b4..038460141 100644 --- a/lib/pact_broker/services.rb +++ b/lib/pact_broker/services.rb @@ -71,5 +71,10 @@ def webhook_trigger_service require 'pact_broker/webhooks/trigger_service' Webhooks::TriggerService end + + def metrics_service + require 'pact_broker/metrics/service' + Metrics::Service + end end end diff --git a/spec/features/metrics_spec.rb b/spec/features/metrics_spec.rb new file mode 100644 index 000000000..3934e68ae --- /dev/null +++ b/spec/features/metrics_spec.rb @@ -0,0 +1,23 @@ +describe "get metrics" do + let(:path) { "/metrics"} + let(:json_response_body) { JSON.parse(subject.body, symbolize_names: true) } + + subject { get(path) } + + before do + TestDataBuilder.new + .create_consumer("Consumer") + .create_provider("Provider") + .create_consumer_version("1.2.3") + .create_consumer_version_tag("prod") + .create_pact + .create_verification(provider_version: "4.5.6") + .create_webhook + .create_triggered_webhook + .create_webhook_execution + end + + it "returns some metrics" do + expect(json_response_body).to be_instance_of(Hash) + end +end