Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement archive record function #144

Merged
merged 1 commit into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions csp_billing_adapter/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
csp_hookspecs,
hookspecs,
storage_hookspecs,
archive_hookspecs,
hookimpls
)

Expand All @@ -71,6 +72,7 @@ def get_plugin_manager() -> pluggy.PluginManager:
pm.add_hookspecs(hookspecs)
pm.add_hookspecs(csp_hookspecs)
pm.add_hookspecs(storage_hookspecs)
pm.add_hookspecs(archive_hookspecs)
pm.register(hookimpls)
pm.load_setuptools_entrypoints('csp_billing_adapter')
return pm
Expand Down
55 changes: 55 additions & 0 deletions csp_billing_adapter/archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@

"""Utility functions for handling a rolling dictionary archive."""

import functools
import logging

from csp_billing_adapter.config import Config
from csp_billing_adapter.utils import retry_on_exception

log = logging.getLogger('CSPBillingAdapter')

DEFAULT_RETENTION_PERIOD = 6 # in months


def append_metering_records(
archive: list,
Expand Down Expand Up @@ -45,3 +55,48 @@ def append_metering_records(
return archive[1:]
else:
return archive


def archive_record(
hook,
config: Config,
billing_record: dict
) -> None:
"""
:param hook:
The Pluggy plugin manager hook that will be
used to call the meter_billing operation.
:param config:
The configuration specifying the metrics that
need to be processed in the usage records list.
:param billing_record:
The dictionary containing the most recent
metering and usage records to be archived.
"""
archive = retry_on_exception(
functools.partial(
hook.get_metering_archive,
config=config,
),
logger=log,
func_name="hook.get_metering_archive"
)

if archive is None:
archive = []
smarlowucf marked this conversation as resolved.
Show resolved Hide resolved

archive = append_metering_records(
archive,
billing_record,
config.archive_retention_period or DEFAULT_RETENTION_PERIOD
)

retry_on_exception(
functools.partial(
hook.save_metering_archive,
config=config,
archive_data=archive
),
logger=log,
func_name="hook.save_metering_archive"
)
15 changes: 15 additions & 0 deletions csp_billing_adapter/bill_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
string_to_date
)
from csp_billing_adapter.config import Config
from csp_billing_adapter.archive import archive_record

log = logging.getLogger('CSPBillingAdapter')

Expand Down Expand Up @@ -655,3 +656,17 @@ def process_metering(
)
csp_config['usage'] = billable_usage
csp_config['last_billed'] = metering_time

# Save last usage and metering records to archive
billing_record = {
'billing_time': metering_time,
'billing_status': billing_status,
'billed_usage': billed_dimensions,
'usage_records': billable_records
}

archive_record(
hook,
config,
billing_record
)
16 changes: 16 additions & 0 deletions csp_billing_adapter/memory_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,26 @@

import csp_billing_adapter

from csp_billing_adapter.config import Config

memory_archive = []

log = logging.getLogger('CSPBillingAdapter')


@csp_billing_adapter.hookimpl(trylast=True)
def get_archive_location():
"""Retrieve archive location."""
return '/tmp/fake_archive.json'


@csp_billing_adapter.hookimpl(trylast=True)
def get_metering_archive(config: Config):
return memory_archive.copy()


@csp_billing_adapter.hookimpl(trylast=True)
def save_metering_archive(config: Config, archive_data: list):
global memory_archive

memory_archive = archive_data
3 changes: 3 additions & 0 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ def cba_pm(cba_config):
# reset the in-memory csp_config to empty
pm.hook.save_csp_config(config=cba_config, csp_config=dict())

# reset the in-memory archive to empty
pm.hook.save_metering_archive(config=cba_config, archive_data=list())

return pm


Expand Down
45 changes: 44 additions & 1 deletion tests/unit/test_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
for the archive util functions.
"""

from csp_billing_adapter.archive import append_metering_records
from csp_billing_adapter.archive import (
append_metering_records,
archive_record
)


def test_append_metering_records():
Expand All @@ -40,3 +43,43 @@ def test_append_metering_records():

assert len(archive) == 6
assert archive[4] == records


def test_archive_record(cba_pm, cba_config):
record = {
'billing_time': '2024-02-09T18:11:59.527064+00:00',
'billing_status': {
'tier_1': {
'record_id': 'd92c6e6556b14770994f5b64ebe3d339',
'status': 'succeeded'
}
},
'billed_usage': {
'tier_1': 10
},
'usage_records': [
{
'managed_node_count': 9,
'reporting_time': '2024-01-09T18:11:59.527673+00:00',
'base_product': 'cpe:/o:suse:product:v1.2.3'
},
{
'managed_node_count': 9,
'reporting_time': '2024-01-09T18:11:59.529096+00:00',
'base_product': 'cpe:/o:suse:product:v1.2.3'
},
{
'managed_node_count': 10,
'reporting_time': '2024-01-09T18:11:59.531424+00:00',
'base_product': 'cpe:/o:suse:product:v1.2.3'
}
]
}
archive_record(
cba_pm.hook,
cba_config,
record
)
archive = cba_pm.hook.get_metering_archive(config=cba_config)
assert len(archive) == 1
assert archive[0] == record
Loading