marketplacemetering

package
v1.8.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2026 License: MIT Imports: 27 Imported by: 0

README

Marketplacemetering

Parity grade: B · SDK aws-sdk-go-v2/service/marketplacemetering@v1.46.2 · last audited 2026-10-18 (8d07d8213)

Coverage

Metric Value
PARITY entries audited 4 (4 ok)
Feature families 3 (3 ok)
Known gaps 5
Structural gaps (can't be emulated) 2
Deferred items 0
Resource leaks clean
Known gaps
  • License-based metering (LicenseArn / concurrent agreements): BatchMeterUsage needs a ProductCode and LicenseArn is only echoed; there is no license catalog
  • Seeding is Go-API only (RegisterProduct, Subscribe, IssueRegistrationToken); there is no HTTP or config surface to declare products for out-of-process clients
  • RegisterUsage signature is HS256 with an emulator key and PublicKeyRotationTimestamp is the product's first-seen time plus 90 days; clients cannot verify it against the AWS Marketplace public key
  • Usage is deduplicated per second-resolution timestamp; the real service aggregates per hour
  • InvalidRegionException, InvalidEndpointRegionException, PlatformNotSupportedException, DisabledApiException, InvalidLicenseException and ThrottlingException are never raised
Structural gaps

These do not block an A grade — no implementation could produce real data here because the underlying data source cannot exist in an emulator.

  • No EC2 instance, ECS task or EKS pod identity exists to bind a product code to, so the region/platform checks of MeterUsage and RegisterUsage have no data source.
  • No billing system: metered usage is stored and queryable but never invoiced.

More

Documentation

Overview

Package marketplacemetering emulates AWS Marketplace Metering: MeterUsage, BatchMeterUsage, RegisterUsage and ResolveCustomer, with entitlements derived for the Marketplace Entitlement Service.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrCustomerNotEntitled       = errors.New("customer not entitled")
	ErrDuplicateRequest          = errors.New("duplicate request")
	ErrExpiredToken              = errors.New("expired token")
	ErrIdempotencyConflict       = errors.New("idempotency conflict")
	ErrInternalServiceError      = errors.New("internal service error")
	ErrInvalidCustomerIdentifier = errors.New("invalid customer identifier")
	ErrInvalidProductCode        = errors.New("invalid product code")
	ErrInvalidPublicKeyVersion   = errors.New("invalid public key version")
	ErrInvalidTag                = errors.New("invalid tag")
	ErrInvalidToken              = errors.New("invalid token")
	ErrInvalidUsageAllocations   = errors.New("invalid usage allocations")
	ErrInvalidUsageDimension     = errors.New("invalid usage dimension")
	ErrTimestampOutOfBounds      = errors.New("timestamp out of bounds")
	ErrValidation                = errors.New("validation")
	ErrDryRunOperation           = errors.New("dry run operation")
)

Sentinels, one per exception in the pinned SDK's error set (plus ValidationException and DryRunOperation).

Functions

This section is empty.

Types

type BatchMeterUsageInput

type BatchMeterUsageInput struct {
	ProductCode  string        `json:"ProductCode"`
	UsageRecords []UsageRecord `json:"UsageRecords"`
}

BatchMeterUsageInput is the BatchMeterUsage request.

type BatchMeterUsageOutput

type BatchMeterUsageOutput struct {
	Results            []UsageRecordResult `json:"Results"`
	UnprocessedRecords []UsageRecord       `json:"UnprocessedRecords"`
}

BatchMeterUsageOutput is the BatchMeterUsage response.

type Dimension

type Dimension struct {
	ExpiresAt *awstime.EpochTime `json:"expiresAt,omitempty"`
	Value     *ent.Value         `json:"value,omitempty"`
	Name      string             `json:"name"`
}

Dimension is one metered or entitled dimension of a declared product.

type EntitlementSink

type EntitlementSink interface {
	GrantEntitlement(e ent.Entitlement) error
	RevokeEntitlements(productCode, customerIdentifier string)
}

EntitlementSink receives the entitlements derived from customer subscriptions.

type Handler

type Handler struct {
	Backend *InMemoryBackend
	// contains filtered or unexported fields
}

Handler serves the Marketplace Metering awsjson1.1 API.

func NewHandler

func NewHandler(backend *InMemoryBackend) *Handler

NewHandler wraps a backend.

func (*Handler) ChaosOperations

func (h *Handler) ChaosOperations() []string

ChaosOperations lists the fault-injectable operations.

func (*Handler) ChaosRegions

func (h *Handler) ChaosRegions() []string

ChaosRegions lists the regions this handler serves.

func (*Handler) ChaosServiceName

func (h *Handler) ChaosServiceName() string

ChaosServiceName returns the lowercase service name for fault rules.

func (*Handler) ExtractOperation

func (h *Handler) ExtractOperation(c *echo.Context) string

ExtractOperation returns the operation name from X-Amz-Target.

func (*Handler) ExtractResource

func (h *Handler) ExtractResource(c *echo.Context) string

ExtractResource returns the operation name; the API has no single resource key.

func (*Handler) GetSupportedOperations

func (h *Handler) GetSupportedOperations() []string

GetSupportedOperations lists every routed operation.

func (*Handler) Handler

func (h *Handler) Handler() echo.HandlerFunc

Handler returns the echo handler.

func (*Handler) MatchPriority

func (h *Handler) MatchPriority() int

MatchPriority returns the routing priority.

func (*Handler) Name

func (h *Handler) Name() string

Name returns the service name.

func (*Handler) Reset

func (h *Handler) Reset()

Reset clears all state.

func (*Handler) Restore

func (h *Handler) Restore(ctx context.Context, data []byte) error

Restore implements persistence.Persistable.

func (*Handler) RouteMatcher

func (h *Handler) RouteMatcher() service.Matcher

RouteMatcher matches the AWSMPMeteringService X-Amz-Target prefix.

func (*Handler) Snapshot

func (h *Handler) Snapshot(ctx context.Context) []byte

Snapshot implements persistence.Persistable.

type InMemoryBackend

type InMemoryBackend struct {
	// contains filtered or unexported fields
}

InMemoryBackend holds products, subscriptions, usage and registrations behind one coarse lock.

func NewInMemoryBackend

func NewInMemoryBackend(accountID, region string) *InMemoryBackend

NewInMemoryBackend creates an empty backend.

func (*InMemoryBackend) BatchMeterUsage

BatchMeterUsage meters up to 25 customer records of one product; rejected records come back unprocessed.

func (*InMemoryBackend) IssueRegistrationToken

func (b *InMemoryBackend) IssueRegistrationToken(productCode, accountID string) (string, error)

IssueRegistrationToken mints the token the Marketplace console would redirect a new subscriber with. Tokens are HMAC-signed and valid for four hours.

func (*InMemoryBackend) MeterUsage

MeterUsage records hourly usage of one dimension for the calling account's product subscription. A repeat of the same (product, customer, dimension, timestamp) with the same quantity returns the original record; with another quantity it fails with DuplicateRequestException.

func (*InMemoryBackend) Region

func (b *InMemoryBackend) Region() string

Region returns the home region.

func (*InMemoryBackend) RegisterProduct

func (b *InMemoryBackend) RegisterProduct(spec ProductSpec) error

RegisterProduct declares a product. Customers that subscribed earlier get the new dimensions' entitlements.

func (*InMemoryBackend) RegisterUsage

RegisterUsage validates the product and public key version, records the registration and returns an HS256-signed token over the product, nonce and account (the emulator signs with its own key).

func (*InMemoryBackend) Registrations

func (b *InMemoryBackend) Registrations(productCode string) []Registration

Registrations returns the RegisterUsage calls recorded for a product.

func (*InMemoryBackend) Reset

func (b *InMemoryBackend) Reset()

Reset clears every table.

func (*InMemoryBackend) ResolveCustomer

func (b *InMemoryBackend) ResolveCustomer(token string) (*ResolvedCustomer, error)

ResolveCustomer verifies a registration token, subscribes the customer to the product and returns the identity.

func (*InMemoryBackend) Restore

func (b *InMemoryBackend) Restore(ctx context.Context, data []byte) error

Restore loads a snapshot; an incompatible version is discarded.

func (*InMemoryBackend) SetClock

func (b *InMemoryBackend) SetClock(now func() time.Time)

SetClock replaces the time source.

func (*InMemoryBackend) SetEntitlementSink

func (b *InMemoryBackend) SetEntitlementSink(s EntitlementSink)

SetEntitlementSink wires the Marketplace Entitlement Service backend that receives subscription entitlements.

func (*InMemoryBackend) Snapshot

func (b *InMemoryBackend) Snapshot(ctx context.Context) []byte

Snapshot serialises the backend state.

func (*InMemoryBackend) Subscribe

func (b *InMemoryBackend) Subscribe(productCode, accountID string) (*Subscription, error)

Subscribe records account as a customer of the product and grants the product's entitlements.

func (*InMemoryBackend) Unsubscribe

func (b *InMemoryBackend) Unsubscribe(productCode, accountID string)

Unsubscribe removes a customer's subscription and the entitlements derived from it.

func (*InMemoryBackend) UsageRecords

func (b *InMemoryBackend) UsageRecords(productCode string) []StoredUsage

UsageRecords returns the metering records stored for a product, oldest first.

type MeterUsageInput

type MeterUsageInput struct {
	Timestamp        *awstime.EpochTime `json:"Timestamp,omitempty"`
	UsageQuantity    *int32             `json:"UsageQuantity,omitempty"`
	DryRun           *bool              `json:"DryRun,omitempty"`
	ProductCode      string             `json:"ProductCode"`
	UsageDimension   string             `json:"UsageDimension"`
	ClientToken      string             `json:"ClientToken,omitempty"`
	UsageAllocations []UsageAllocation  `json:"UsageAllocations,omitempty"`
}

MeterUsageInput is the MeterUsage request.

type MeterUsageOutput

type MeterUsageOutput struct {
	MeteringRecordID string `json:"MeteringRecordId,omitempty"`
}

MeterUsageOutput is the MeterUsage response.

type Product

type Product struct {
	RegisteredAt     awstime.EpochTime `json:"registeredAt"`
	Code             string            `json:"code"`
	Dimensions       []Dimension       `json:"dimensions,omitempty"`
	PublicKeyVersion int32             `json:"publicKeyVersion"`
	Declared         bool              `json:"declared"`
}

Product is a Marketplace product known to the emulator. Declared products enforce their dimensions and require a customer subscription; undeclared (implicit) products accept any dimension and customer.

type ProductSpec

type ProductSpec struct {
	Code             string
	Dimensions       []Dimension
	PublicKeyVersion int32
}

ProductSpec declares a product; a declared product enforces its dimensions and customer subscriptions.

type Provider

type Provider struct{}

Provider implements service.Provider for AWS Marketplace Metering.

func (*Provider) Init

Init builds the backend and handler.

func (*Provider) Name

func (p *Provider) Name() string

Name returns the provider name.

type RegisterUsageInput

type RegisterUsageInput struct {
	PublicKeyVersion *int32 `json:"PublicKeyVersion,omitempty"`
	ProductCode      string `json:"ProductCode"`
	Nonce            string `json:"Nonce,omitempty"`
}

RegisterUsageInput is the RegisterUsage request.

type RegisterUsageOutput

type RegisterUsageOutput struct {
	PublicKeyRotationTimestamp *awstime.EpochTime `json:"PublicKeyRotationTimestamp,omitempty"`
	Signature                  string             `json:"Signature,omitempty"`
}

RegisterUsageOutput is the RegisterUsage response.

type Registration

type Registration struct {
	RegisteredAt     awstime.EpochTime `json:"registeredAt"`
	ID               string            `json:"id"`
	ProductCode      string            `json:"productCode"`
	Nonce            string            `json:"nonce,omitempty"`
	AccountID        string            `json:"accountId"`
	PublicKeyVersion int32             `json:"publicKeyVersion"`
}

Registration is a RegisterUsage call.

type ResolvedCustomer

type ResolvedCustomer struct {
	CustomerAWSAccountID string `json:"CustomerAWSAccountId"`
	CustomerIdentifier   string `json:"CustomerIdentifier"`
	ProductCode          string `json:"ProductCode"`
}

ResolvedCustomer is the ResolveCustomer result.

type StoredUsage

type StoredUsage struct {
	Timestamp            awstime.EpochTime `json:"timestamp"`
	RecordedAt           awstime.EpochTime `json:"recordedAt"`
	ID                   string            `json:"id"`
	ProductCode          string            `json:"productCode"`
	CustomerIdentifier   string            `json:"customerIdentifier"`
	CustomerAWSAccountID string            `json:"customerAwsAccountId"`
	Dimension            string            `json:"dimension"`
	Operation            string            `json:"operation"`
	Allocations          []UsageAllocation `json:"allocations,omitempty"`
	Quantity             int32             `json:"quantity"`
}

StoredUsage is a metering record accepted by MeterUsage or BatchMeterUsage.

type Subscription

type Subscription struct {
	CreatedAt            awstime.EpochTime `json:"createdAt"`
	ProductCode          string            `json:"productCode"`
	CustomerAWSAccountID string            `json:"customerAwsAccountId"`
	CustomerIdentifier   string            `json:"customerIdentifier"`
}

Subscription ties a customer account to a product.

type Tag

type Tag struct {
	Key   string `json:"Key"`
	Value string `json:"Value"`
}

Tag is a UsageAllocation tag.

type UsageAllocation

type UsageAllocation struct {
	Tags                   []Tag `json:"Tags,omitempty"`
	AllocatedUsageQuantity int32 `json:"AllocatedUsageQuantity"`
}

UsageAllocation splits a usage quantity across a unique tag set.

type UsageRecord

type UsageRecord struct {
	Timestamp            *awstime.EpochTime `json:"Timestamp,omitempty"`
	Quantity             *int32             `json:"Quantity,omitempty"`
	CustomerAWSAccountID string             `json:"CustomerAWSAccountId,omitempty"`
	CustomerIdentifier   string             `json:"CustomerIdentifier,omitempty"`
	Dimension            string             `json:"Dimension,omitempty"`
	LicenseArn           string             `json:"LicenseArn,omitempty"`
	UsageAllocations     []UsageAllocation  `json:"UsageAllocations,omitempty"`
}

UsageRecord is the BatchMeterUsage record shape; timestamps are epoch-seconds numbers.

type UsageRecordResult

type UsageRecordResult struct {
	UsageRecord      *UsageRecord `json:"UsageRecord,omitempty"`
	MeteringRecordID string       `json:"MeteringRecordId,omitempty"`
	Status           string       `json:"Status"`
}

UsageRecordResult is one BatchMeterUsage per-record outcome.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL