Skip to content

Commit

Permalink
LITE-28076 Add retry action for deployment requests
Browse files Browse the repository at this point in the history
  • Loading branch information
jonatrios committed Aug 4, 2023
1 parent 8e78814 commit 2742162
Show file tree
Hide file tree
Showing 10 changed files with 540 additions and 229 deletions.
2 changes: 2 additions & 0 deletions connect_ext_ppr/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ class ExtensionHttpError(ExtensionErrorBase):
15: 'No Marketplace is linked with Deployment Hub {hub_id}',
16: "Pricing Batch '{batch_id}' does not have any file.",
17: "Cannot create a new request, an open one already exists.",
18: "Deployment request `{dep_request_id}` can not be retried, newer requests were"
" created for related deployment `{deployment_id}`: {new_requests}.",
}


Expand Down
5 changes: 5 additions & 0 deletions connect_ext_ppr/models/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ def abort_by_api(self, by):
self.aborted_at = datetime.utcnow()
self.aborted_by = by

@transition('status', target=STATUSES.pending, sources=[STATUSES.error])
def retry(self):
self.started_at = None
self.finished_at = None


class MarketplaceConfiguration(Model):
__tablename__ = 'marketplace_configuration'
Expand Down
5 changes: 5 additions & 0 deletions connect_ext_ppr/models/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,8 @@ class Task(Model):
def abort(self, by):
self.aborted_at = datetime.utcnow()
self.aborted_by = by

@transition('status', target=STATUSES.pending, sources=[STATUSES.error])
def retry(self):
self.started_at = None
self.finished_at = None
60 changes: 60 additions & 0 deletions connect_ext_ppr/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
get_configuration_from_media,
get_ppr_from_media,
get_product_items,
get_user_data_from_auth_token,
process_ppr,
validate_configuration_schema,
validate_ppr_schema,
Expand Down Expand Up @@ -410,3 +411,62 @@ def deactivate_marketplaces(installation, listings, config, logger):
)

db.commit()


class DeploymentRequestActionHandler:

@classmethod
def abort(cls, request, db, deployment_request):
origin_state = deployment_request.status
user_data = get_user_data_from_auth_token(request.headers['connect-auth'])
by = user_data['id']
deployment_request.aborting(by)
db.flush()
tasks = (
db
.query(Task)
.filter_by(deployment_request=deployment_request.id, status=Task.STATUSES.pending)
.with_for_update()
)
for task in tasks:
task.abort(by)
db.flush()
if origin_state == DeploymentRequest.STATUSES.pending:
deployment_request.abort_by_api(by)
db.commit()
return deployment_request

@classmethod
def retry(cls, db, deployment_request):
most_recent_requests = (
db
.query(DeploymentRequest)
.filter(
DeploymentRequest.created_at > deployment_request.created_at,
DeploymentRequest.deployment_id == deployment_request.deployment_id,
)
.order_by(DeploymentRequest.created_at.desc())
)
if db.query(most_recent_requests.exists()).scalar():
new_requests = (
', '.join("(request_id={0}, status={1})"
.format(req.id, req.status) for req in most_recent_requests)
)
raise ExtensionHttpError.EXT_018(
format_kwargs={
'dep_request_id': deployment_request.id,
'deployment_id': deployment_request.deployment_id,
'new_requests': new_requests,
},
)
deployment_request.retry()
db.flush()
tasks = (
db
.query(Task)
.filter_by(deployment_request=deployment_request.id, status=Task.STATUSES.error)
)
for task in tasks:
task.retry()
db.commit()
return deployment_request
2 changes: 2 additions & 0 deletions connect_ext_ppr/tasks_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def main_process(deployment_request_id, config):
if deployment_request.status != DeploymentRequestStatusChoices.pending:
return deployment_request.status

deployment_request.started_at = datetime.utcnow()
deployment = deployment_request.deployment
deployment.status = DeploymentStatusChoices.processing
deployment_request.status = DeploymentRequestStatusChoices.processing
Expand All @@ -94,6 +95,7 @@ def main_process(deployment_request_id, config):
else:
deployment_request.status = DeploymentRequestStatusChoices.error

deployment_request.finished_at = datetime.utcnow()
db.add(deployment_request)
db.commit()

Expand Down
41 changes: 24 additions & 17 deletions connect_ext_ppr/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
add_new_deployment_request,
create_ppr,
deactivate_marketplaces,
DeploymentRequestActionHandler,
validate_configuration,
)
from connect_ext_ppr.schemas import (
Expand Down Expand Up @@ -121,6 +122,7 @@ class ConnectExtensionXvsWebApplication(WebApplicationBase):
'/deployments/requests',
summary='Create a new deployment request',
response_model=DeploymentRequestSchema,
status_code=status.HTTP_201_CREATED,
)
def add_dep_request(
self,
Expand Down Expand Up @@ -301,24 +303,29 @@ def abort(
request: Request = None,
):
dr = get_deployment_request_by_id(depl_req_id, db, installation)
origin_state = dr.status
dr = DeploymentRequestActionHandler.abort(request, db, dr)
hub = get_hub(client, dr.deployment.hub_id)
return get_deployment_request_schema(dr, hub)

@router.post(
'/deployments/requests/{depl_req_id}/retry',
summary='Retry a deployment request',
response_model=DeploymentRequestSchema,
)
def retry(
self,
depl_req_id: str,
background_tasks: BackgroundTasks,
db: VerboseBaseSession = Depends(get_db),
client: ConnectClient = Depends(get_installation_client),
installation: dict = Depends(get_installation),
config: dict = Depends(get_config),
):
dr = get_deployment_request_by_id(depl_req_id, db, installation)
dr = DeploymentRequestActionHandler.retry(db, dr)

background_tasks.add_task(main_process, dr.id, config)

tasks = (
db
.query(Task)
.filter_by(deployment_request=dr.id, status=Task.STATUSES.pending)
.with_for_update()
)
user_data = get_user_data_from_auth_token(request.headers['connect-auth'])
by = user_data['id']
dr.aborting(by)
db.flush()
for task in tasks:
task.abort(by)
db.flush()
if origin_state == DeploymentRequest.STATUSES.pending:
dr.abort_by_api(by)
db.commit()
hub = get_hub(client, dr.deployment.hub_id)
return get_deployment_request_schema(dr, hub)

Expand Down
Loading

0 comments on commit 2742162

Please sign in to comment.