Skip to content

Commit

Permalink
LITE-28160 Regenerate ppr when product version change
Browse files Browse the repository at this point in the history
  • Loading branch information
jonatrios committed Jul 25, 2023
1 parent 29b7c48 commit 68578ba
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 50 deletions.
9 changes: 7 additions & 2 deletions connect_ext_ppr/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from connect.eaas.core.responses import BackgroundResponse
from sqlalchemy.exc import DBAPIError

from connect_ext_ppr.service import add_deployments, update_product
from connect_ext_ppr.service import add_deployments, process_ppr_from_product_update
from connect_ext_ppr.utils import get_all_info, get_marketplaces, get_products


Expand Down Expand Up @@ -74,7 +74,12 @@ def handle_product_changed(self, request):
db, create a new one.
'''
self.logger.info(f"Product {request['id']} changed.")
update_product(request, self.config, self.logger)
try:
process_ppr_from_product_update(
request, self.config, self.context, self.installation_client, self.logger,
)
except (ClientError, DBAPIError):
return BackgroundResponse.reschedule()
return BackgroundResponse.done()

@event(
Expand Down
50 changes: 31 additions & 19 deletions connect_ext_ppr/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from connect_ext_ppr.models.file import File
from connect_ext_ppr.models.ppr import PPRVersion
from connect_ext_ppr.models.replicas import Product
from connect_ext_ppr.schemas import FileSchema
from connect_ext_ppr.schemas import FileSchema, PPRCreateSchema
from connect_ext_ppr.utils import (
create_ppr_to_media,
get_base_workbook,
Expand Down Expand Up @@ -85,18 +85,27 @@ def add_deployments(installation, listings, config, logger):
logger.info(f"The following Deployments have been created: {dep_ids}.")


def update_product(data, config, logger):
product_id = data['id']
def process_ppr_from_product_update(data, config, context, client, logger):
with get_db_ctx_manager(config) as db:
q = db.query(Product).filter_by(id=product_id)
q = db.query(Deployment).filter_by(product_id=data['id'])
if db.query(q.exists()).scalar():
logger.info(f"Updating product: {product_id}.")
product = q.first()
product.name = data['name']
product.logo = data.get('icon')
product.version = data['version']
db.add(product)
db.commit()
deployment = q.first()
product = deployment.product
older_version = product.version
update_product(data, db, product, logger)
if data['version'] > older_version:
ppr = PPRCreateSchema()
logger.info(f"Product version changed: {older_version} -> {data['version']}.")
create_ppr(ppr, context, deployment, db, client, logger)


def update_product(data, db, product, logger):
logger.info(f"Updating product: {product.id}.")
product.name = data['name']
product.logo = data.get('icon')
product.version = data['version']
db.add(product)
db.commit()


def get_ppr_new_version(db, deployment):
Expand All @@ -116,6 +125,7 @@ def create_ppr(ppr, context, deployment, db, client, logger):
file_data = ppr.file
new_version = get_ppr_new_version(db, deployment)
config_kwargs = {}
config_json = {}
status = PPRVersion.STATUS.ready
if not file_data:
active_configuration = (
Expand All @@ -125,11 +135,11 @@ def create_ppr(ppr, context, deployment, db, client, logger):
state=Configuration.STATE.active,
).one_or_none()
)
if not active_configuration:
raise ExtensionHttpError.EXT_006(
format_kwargs={'deployment_id': deployment.id},
if active_configuration:
config_kwargs.update({'configuration': active_configuration.id})
config_json = get_configuration_from_media(
client, deployment.account_id, deployment.id, active_configuration.file,
)
config_kwargs.update({'configuration': active_configuration.id})
previous_ppr = (
db.query(PPRVersion)
.filter_by(
Expand All @@ -140,9 +150,6 @@ def create_ppr(ppr, context, deployment, db, client, logger):
.first()
)
data = None
config_json = get_configuration_from_media(
client, deployment.account_id, deployment.id, active_configuration.file,
)
product_info = (
f"(product_id={deployment.product_id}, "
f"product_version={deployment.product.version})"
Expand All @@ -158,7 +165,7 @@ def create_ppr(ppr, context, deployment, db, client, logger):
else:
logger.info(
f"Start creation of PPR version {product_info}"
f" based on previous product information.",
f" based on product information.",
)
items = list(get_product_items(client, deployment.product.id))

Expand Down Expand Up @@ -223,6 +230,11 @@ def create_ppr(ppr, context, deployment, db, client, logger):
)
db.set_verbose(new_ppr)
db.commit()

logger.info(
f"New PPR version created: (id={new_ppr.id}, version={new_ppr.version}"
f", product_version={new_ppr.product_version}, file={new_ppr.file}).",
)
return new_ppr

except DBAPIError as ex:
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def _build_deployment(
vendor_id='VA-000-000',
hub_id='HB-0000-0000',
):
product = product_factory(product_id)
product = product_factory(id=product_id, owner_id=vendor_id)
product_id = product.id

dep = Deployment(
Expand Down
89 changes: 87 additions & 2 deletions tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
# Copyright (c) 2023, Ingram Micro
# All rights reserved.
#
import json

from connect.client import ClientError
from connect.client.rql import R
import pytest

from connect_ext_ppr.events import ConnectExtensionXvsEventsApplication
from connect_ext_ppr.models.ppr import PPRVersion
from connect_ext_ppr.models.replicas import Product


Expand Down Expand Up @@ -109,14 +112,17 @@ def test_handle_product_changed(
logger,
installation,
product,
product_factory,
common_context,
deployment_factory,
):
config = {}
product_obj = product_factory(id=product['id'], owner_id='VA-123-123')
deployment = deployment_factory(product_id=product['id'], vendor_id='VA-123-123')
product_obj = deployment.product
ext = ConnectExtensionXvsEventsApplication(
connect_client, logger, config,
installation=installation,
installation_client=connect_client,
context=common_context,
)
result = ext.handle_product_changed(product)
assert result.status == 'success'
Expand All @@ -133,20 +139,99 @@ def test_ignore_product_changed(
logger,
installation,
product,
common_context,
):
config = {}

ext = ConnectExtensionXvsEventsApplication(
connect_client, logger, config,
installation=installation,
installation_client=connect_client,
context=common_context,
)
result = ext.handle_product_changed(product)
assert result.status == 'success'
q = dbsession.query(Product).filter_by(id=product['id'])
assert not dbsession.query(q.exists()).scalar()


def test_handle_ppr_creation_from_product_update(
product,
item_response,
media_response,
dbsession,
logger,
installation,
common_context,
connect_client,
deployment_factory,
configuration_factory,
configuration_json,
client_mocker_factory,
file_factory,
):
config = {}
product_version = product['version'] = 4
dep = deployment_factory(product_id=product['id'])
config_file = file_factory(
id='MFL-YYY',
mime_type='application/json',
)
configuration_factory(file=config_file.id, deployment=dep.id)
client_mocker = client_mocker_factory(base_url=connect_client.endpoint)
client_mocker.ns('media').ns('folders').ns('accounts').collection(
f'{dep.account_id}/{dep.id}/configurations/files',
)[config_file.id].get(
return_value=configuration_json,
)

client_mocker.products[dep.product_id].items.all().mock(
return_value=[item_response],
)

client_mocker.ns('media').ns('folders').ns('accounts').collection(
f'{dep.account_id}/{dep.id}/pprs/files',
).create(
return_value=json.dumps(media_response),
)

ext = ConnectExtensionXvsEventsApplication(
connect_client, logger, config,
installation=installation,
installation_client=connect_client,
context=common_context,
)
qs = dbsession.query(PPRVersion).filter_by(deployment=dep.id, product_version=product_version)
result = ext.handle_product_changed(product)
assert result.status == 'success'
assert qs.count() == 1
assert qs.first().file == media_response['id']


def test_reschedule_product_change(
product,
dbsession,
logger,
installation,
common_context,
connect_client,
mocker,
):
config = {}
ext = ConnectExtensionXvsEventsApplication(
connect_client, logger, config,
installation=installation,
installation_client=connect_client,
context=common_context,
)
mocker.patch(
'connect_ext_ppr.events.process_ppr_from_product_update',
side_effect=ClientError,
)
result = ext.handle_product_changed(product)
assert result.status == 'reschedule'


@pytest.mark.parametrize(
'status',
('installed', 'uninstalled'),
Expand Down
Loading

0 comments on commit 68578ba

Please sign in to comment.