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

LITE-28562 Implement delegate_to_l2 task #110

Merged
merged 1 commit into from
Sep 20, 2023
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
1 change: 1 addition & 0 deletions connect_ext_ppr/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@
],
}
PPR_FILE_NAME = "PPR_{product_id}_v{version}_{timestamp}.xlsx"
PPR_FILE_NAME_DELEGATION_L2 = "{dr_id}-L2Delegation-{ppr_id}-{timestamp}.xlsx"
DESCRIPTION_TEMPLATE = """
**Description**
{description}
Expand Down
2 changes: 1 addition & 1 deletion connect_ext_ppr/models/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Task(Model):
)
deployment_request_id = db.Column(db.ForeignKey(DeploymentRequest.id))
title = db.Column(db.String(100))
error_message = db.Column(db.String((4000)))
error_message = db.Column(db.String(4000))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just fixed typo

type = db.Column(db.Enum(TaskTypesChoices, validate_strings=True))

created_at = db.Column(db.DateTime(), default=datetime.utcnow)
Expand Down
6 changes: 2 additions & 4 deletions connect_ext_ppr/service.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
from datetime import datetime

import pandas as pd
Expand All @@ -25,6 +24,7 @@
create_ppr_to_media,
get_base_workbook,
get_configuration_from_media,
get_file_size,
get_ppr_from_media,
get_product_items,
get_user_data_from_auth_token,
Expand Down Expand Up @@ -238,9 +238,7 @@ def create_ppr(ppr, user_id, deployment, db, client, logger):
file_obj = open(file.name, 'rb')
writer.book.save(file_obj.name)

file_obj.seek(0, os.SEEK_END)
file_size = file_obj.tell()
file_obj.seek(0)
file_size = get_file_size(file_obj)
file_name = PPR_FILE_NAME.format(
product_id=deployment.product_id,
version=new_version,
Expand Down
87 changes: 82 additions & 5 deletions connect_ext_ppr/tasks_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from sqlalchemy.orm import joinedload, selectinload

from connect_ext_ppr.client.exception import ClientError
from connect_ext_ppr.constants import PPR_FILE_NAME_DELEGATION_L2
from connect_ext_ppr.db import get_cbc_extension_db, get_db_ctx_manager
from connect_ext_ppr.models.enums import CBCTaskLogStatus
from connect_ext_ppr.models.enums import (
Expand All @@ -18,6 +19,13 @@
from connect_ext_ppr.models.task import Task
from connect_ext_ppr.services.cbc_extension import get_hub_credentials
from connect_ext_ppr.services.cbc_hub import CBCService
from connect_ext_ppr.utils import (
create_dr_file_to_media,
get_base_workbook,
get_file_size,
get_ppr_from_media,
process_ppr_file_for_delelegate_l2,
)


class TaskException(Exception):
Expand Down Expand Up @@ -82,6 +90,51 @@ def _check_cbc_task_status(cbc_service, tracking_id):
raise TaskException(f'Something went wrong with task: {tracking_id}')


def prepare_ppr_file_for_task(
connect_client,
file_data,
file_name_template,
deployment_request,
deployment,
process_func,
):
file, writer, wb = get_base_workbook(file_data)

try:
ws_list = []
for sheet_name in wb.sheet_names:
ws = wb.parse(sheet_name)
process_func(sheet_name, ws)
ws.name = sheet_name
ws_list.append(ws)

for ws in ws_list:
ws.to_excel(writer, ws.name, index=False)
file_obj = open(file.name, 'rb')
writer.book.save(file_obj.name)

file_size = get_file_size(file_obj)
file_name = file_name_template.format(
dr_id=deployment_request.id,
ppr_id=deployment_request.ppr.id,
timestamp=datetime.utcnow().strftime("%s"),
)
create_dr_file_to_media(
connect_client,
deployment.account_id,
deployment_request.id,
file_name,
file_obj.read(),
file_size,
)

file_obj.seek(0)
return file_obj

except (FileNotFoundError, ValueError, KeyError) as e:
raise TaskException(f'Error while processing PPR file: {e}')


def validate_ppr(deployment_request, **kwargs):
return True

Expand Down Expand Up @@ -113,8 +166,31 @@ def apply_ppr_and_delegate_to_marketplaces(deployment_request, **kwargs):
return True


def delegate_to_l2(deployment_request, **kwargs):
return True
def delegate_to_l2(deployment_request, cbc_service, connect_client, **kwargs):
if deployment_request.manually:
return True

ppr_file_id = deployment_request.ppr.file
deployment = deployment_request.deployment
file_data = get_ppr_from_media(
connect_client,
deployment.account_id,
deployment.id,
ppr_file_id,
)

file = prepare_ppr_file_for_task(
connect_client=connect_client,
file_data=file_data,
file_name_template=PPR_FILE_NAME_DELEGATION_L2,
deployment_request=deployment_request,
deployment=deployment,
process_func=process_ppr_file_for_delelegate_l2,
)

tracking_id = _send_ppr(cbc_service, file)
file.close()
return _check_cbc_task_status(cbc_service, tracking_id)


TASK_PER_TYPE = {
Expand All @@ -124,7 +200,7 @@ def delegate_to_l2(deployment_request, **kwargs):
}


def execute_tasks(db, config, tasks):
def execute_tasks(db, config, tasks, connect_client):
was_succesfull = False
cbc_service = _get_cbc_service(config, tasks[0].deployment_request.deployment)

Expand All @@ -140,6 +216,7 @@ def execute_tasks(db, config, tasks):
was_succesfull = TASK_PER_TYPE.get(task.type)(
deployment_request=task.deployment_request,
cbc_service=cbc_service,
connect_client=connect_client,
)
task.status = TasksStatusChoices.done
if not was_succesfull:
Expand All @@ -162,7 +239,7 @@ def execute_tasks(db, config, tasks):
return was_succesfull


def main_process(deployment_request_id, config):
def main_process(deployment_request_id, config, connect_client):

with get_db_ctx_manager(config) as db:
deployment_request = db.query(DeploymentRequest).options(
Expand All @@ -187,7 +264,7 @@ def main_process(deployment_request_id, config):
deployment_request_id=deployment_request_id,
).order_by(Task.id).all()

was_succesfull = execute_tasks(db, config, tasks)
was_succesfull = execute_tasks(db, config, tasks, connect_client)

db.refresh(deployment_request, with_for_update=True)

Expand Down
24 changes: 24 additions & 0 deletions connect_ext_ppr/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@ def create_ppr_to_media(client, account_id, deployment_id, filename, content, fi
return json.loads(media_file)


def create_dr_file_to_media(client, account_id, dr_id, filename, content, file_size=None):
file_collection = FileCollection.PPR
file_type = MimeTypeChoices.application_vnd_ms_xslx
media_file = create_media_file(
client, account_id, dr_id, file_collection,
filename, content, file_type, file_size,
)
return json.loads(media_file)


@connect_error
def get_file_from_media(client, account_id, deployment_id, media_id, file_collection):
return namespaced_media_client(
Expand Down Expand Up @@ -636,3 +646,17 @@ def _build_summary(summary: dict, indent: int = 0):

def build_summary(summary: dict):
return SUMMARY_TEMPLATE.format(summary=_build_summary(summary))


def get_file_size(file_obj):
file_obj.seek(0, os.SEEK_END)
file_size = file_obj.tell()
file_obj.seek(0)
return file_size


def process_ppr_file_for_delelegate_l2(sheet_name, ws):
if sheet_name == 'OpUnitServicePlans':
ws['Published'] = 'TRUE'
elif sheet_name == 'ServicePlans':
ws['Published'] = 'FALSE'
4 changes: 2 additions & 2 deletions connect_ext_ppr/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def add_dep_request(
db, deployment_request, deployment, account_id, logger,
)

self.thread_pool.submit(main_process, instance.id, config)
self.thread_pool.submit(main_process, instance.id, config, client)

hub = get_client_object(client, 'hubs', instance.deployment.hub_id)
response = get_deployment_request_schema(instance, hub)
Expand Down Expand Up @@ -355,7 +355,7 @@ def retry(
dr = get_deployment_request_by_id(depl_req_id, db, installation)
dr = DeploymentRequestActionHandler.retry(db, dr)

self.thread_pool.submit(main_process, dr.id, config)
self.thread_pool.submit(main_process, dr.id, config, client)

hub = get_hub(client, dr.deployment.hub_id)
return get_deployment_request_schema(dr, hub)
Expand Down
21 changes: 5 additions & 16 deletions tests/api/test_pprs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
import os

import pytest

Expand Down Expand Up @@ -278,9 +277,7 @@ def test_upload_ppr(
):
deployment = deployment_factory()

current_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(current_dir, '..', 'fixtures', 'test_PPR_file.xlsx')
with open(file_path, 'rb') as f:
with open('./tests/fixtures/test_PPR_file.xlsx', 'rb') as f:
binary_data = f.read()
mocker.patch(
'connect_ext_ppr.service.get_ppr_from_media',
Expand Down Expand Up @@ -340,9 +337,7 @@ def test_upload_ppr_invalid(
):
deployment = deployment_factory()

current_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(current_dir, '..', 'fixtures', 'test_PPR_file_invalid.xlsx')
with open(file_path, 'rb') as f:
with open('./tests/fixtures/test_PPR_file_invalid.xlsx', 'rb') as f:
binary_data = f.read()
mocker.patch(
'connect_ext_ppr.service.get_ppr_from_media',
Expand Down Expand Up @@ -408,9 +403,7 @@ def test_post_ppr_new_version(
assert dbsession.query(PPRVersion).count() == 1
assert dbsession.query(File).count() == 1

current_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(current_dir, '..', 'fixtures', 'test_PPR_file.xlsx')
with open(file_path, 'rb') as f:
with open('./tests/fixtures/test_PPR_file.xlsx', 'rb') as f:
binary_data = f.read()
mocker.patch(
'connect_ext_ppr.service.get_ppr_from_media',
Expand Down Expand Up @@ -500,9 +493,7 @@ def test_post_ppr_file_already_exists(
file = file_factory(
mime_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
)
current_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(current_dir, '..', 'fixtures', 'test_PPR_file.xlsx')
with open(file_path, 'rb') as f:
with open('./tests/fixtures/test_PPR_file.xlsx', 'rb') as f:
binary_data = f.read()
mocker.patch(
'connect_ext_ppr.service.get_ppr_from_media',
Expand Down Expand Up @@ -545,9 +536,7 @@ def test_generate_ppr(
deployment = deployment_factory(product_id='PRD-XXX-XXX-XXX')
configuration = configuration_factory(deployment=deployment.id)

current_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(current_dir, '..', 'fixtures', 'configuration.json')
with open(file_path, 'rb') as f:
with open('./tests/fixtures/configuration.json', 'rb') as f:
conf_data = json.load(f)
mocker.patch(
'connect_ext_ppr.service.get_configuration_from_media',
Expand Down
38 changes: 25 additions & 13 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
DeploymentRequest,
MarketplaceConfiguration,
)
from connect_ext_ppr.models.enums import TaskTypesChoices
from connect_ext_ppr.models.file import File
from connect_ext_ppr.models.ppr import PPRVersion
from connect_ext_ppr.models.replicas import Account, Product
Expand Down Expand Up @@ -145,12 +146,12 @@ def deployment(dbsession, product_factory):
@pytest.fixture
def deployment_factory(dbsession, product_factory):
def _build_deployment(
id=None,
product_id=None,
account_id='PA-000-000',
vendor_id='VA-000-000',
hub_id='HB-0000-0000',
status='pending',
id=None,
product_id=None,
account_id='PA-000-000',
vendor_id='VA-000-000',
hub_id='HB-0000-0000',
status='pending',
):
product = product_factory(id=product_id, owner_id=vendor_id)
product_id = product.id
Expand All @@ -172,13 +173,13 @@ def _build_deployment(
@pytest.fixture
def deployment_request_factory(dbsession, deployment_factory):
def _build_deployment_request(
deployment=None,
ppr=None,
delegate_l2=False,
status=None,
started_at=None,
finished_at=None,
manually=False,
deployment=None,
ppr=None,
delegate_l2=False,
status=None,
started_at=None,
finished_at=None,
manually=False,
):
if not deployment:
deployment = deployment_factory()
Expand Down Expand Up @@ -1145,3 +1146,14 @@ def connect_auth_header():
def configuration_json():
with open('./tests/fixtures/configuration.json') as json_file:
return json.load(json_file)


@pytest.fixture
def mock_tasks(mocker):
mocker.patch(
'connect_ext_ppr.tasks_manager.TASK_PER_TYPE', return_value={
TaskTypesChoices.ppr_validation: lambda: True,
TaskTypesChoices.apply_and_delegate: lambda: True,
TaskTypesChoices.delegate_to_l2: lambda: True,
},
)
Binary file added tests/fixtures/test_PPR_file_delegate_l2.xlsx
Binary file not shown.
Loading