"""Interface to the ows-product-workflow microservice.""" from oto import response from owsrequest import request import requests from product_digital.constants import error from product_digital.constants import product_statuses from product_digital.constants import services from product_digital.utils import error_handling def create_release_approval_queue(product_id, approval_data): """Create a new record in release approval queue. Args: product_id (str): unique identifier for the product approval_data (dict): dictionary of data for creating an entry Returns: response.Response status of create call and dictionary of results """ ows_product_workflow_response = request.post( services.OWS_PRODUCT_WORKFLOW, '/product/{product_id}/release-approval'.format( product_id=product_id), json=approval_data, ) if ows_product_workflow_response.status_code != 201: error_handling.log_unexpected_response( services.OWS_PRODUCT_WORKFLOW, ows_product_workflow_response ) return response.create_error_response( status=ows_product_workflow_response.status_code, code=error.OWS_PRODUCT_WORKFLOW_ERROR_CODE, message=ows_product_workflow_response.content.decode('utf-8')) info_body = ows_product_workflow_response.json() return response.Response(message=info_body, status=201) def get_last_release_approval_queue(product_id): """Get the last release approval queue for the given product id. Args: product_id (str): unique identifier for the product Returns: response.Response status of create call and dictionary of results """ ows_product_workflow_response = request.get( services.OWS_PRODUCT_WORKFLOW, '/product/{product_id}/release-approval'.format( product_id=product_id), ) info_body = ows_product_workflow_response.json() if ows_product_workflow_response.status_code != 200: return response.create_error_response( status=ows_product_workflow_response.status_code, code=info_body.get('code'), message=info_body.get('message')) return response.Response(message=info_body) def get_rejections(release_approval_id): """Get the rejections belonging to a release approval. Args: release_approval_id (int): the release approval queue id Returns: response.Response: status of rejections call and dictionary of results """ ows_product_workflow_response = request.get( services.OWS_PRODUCT_WORKFLOW, '/release-approval/{release_approval_id}/rejections'.format( release_approval_id=release_approval_id), ) info_body = ows_product_workflow_response.json() if ows_product_workflow_response.status_code != 200: return response.create_error_response( status=ows_product_workflow_response.status_code, code=info_body.get('code'), message=info_body.get('message')) return response.Response(message=info_body) def update_rejections(rejections_data): """Update a collection of rejections. Args: rejections_data (dict): dictionary of data for creating an entry Returns: response.Response status of put call and dictionary of results """ ows_product_workflow_response = request.put( services.OWS_PRODUCT_WORKFLOW, '/release-approval/rejections', json=rejections_data, ) info_body = ows_product_workflow_response.json() if ows_product_workflow_response.status_code != 200: return response.create_error_response( status=ows_product_workflow_response.status_code, code=info_body.get('code'), message=info_body.get('message')) return response.Response(message=info_body) def get_last_release_correction(product_id): """Get the last release correction for the given product id. Args: product_id (int): unique identifier for the product Returns: Response containing the properties of the last release correction. """ ows_product_workflow_response = request.get( services.OWS_PRODUCT_WORKFLOW, '/product/{}/correction'.format(product_id), ) info_body = ows_product_workflow_response.json() if ows_product_workflow_response.status_code not in (200, 404): error_handling.log_unexpected_response( services.OWS_PRODUCT_WORKFLOW, ows_product_workflow_response ) return response.create_error_response( status=ows_product_workflow_response.status_code, code=info_body.get('code'), message=info_body.get('message')) return response.Response( message=info_body, status=ows_product_workflow_response.status_code) def get_release_correction(release_correction_id): """Get a release correction for a given release_correction_id. Args: release_correction_id (str): unique identifier for release_correction. Returns: Response containing the properties of a release correction. """ ows_product_workflow_response = request.get( services.OWS_PRODUCT_WORKFLOW, '/correction/{}'.format(release_correction_id), ) info_body = ows_product_workflow_response.json() if ows_product_workflow_response.status_code != 200: return response.create_error_response( status=ows_product_workflow_response.status_code, code=info_body.get('code'), message=info_body.get('message')) return response.Response(message=info_body) def create_release_correction(product_id, correction_data): """Create a new release correction for the given product. Args: product_id (int): product id correction_data (dict): contents of the new correction record Returns: response.Response: status of post call and dictionary of results """ ows_product_workflow_response = request.post( services.OWS_PRODUCT_WORKFLOW, '/product/{}/correction'.format(product_id), json=correction_data, ) if ows_product_workflow_response.status_code != 201: error_handling.log_unexpected_response( services.OWS_PRODUCT_WORKFLOW, ows_product_workflow_response) return response.create_fatal_response( message='error saving correction') return response.Response( status=ows_product_workflow_response.status_code, message=ows_product_workflow_response.json()) def delete_release_correction(release_correction_id): """Delete a release correction for a given product and release correction. Args: release_correction_id (int): release_correction_id Returns: response.Response: status of delete call and message object """ ows_product_workflow_response = request.delete( services.OWS_PRODUCT_WORKFLOW, '/correction/{}'.format(release_correction_id), ) if ows_product_workflow_response.status_code != 202: error_handling.log_unexpected_response( services.OWS_PRODUCT_WORKFLOW, ows_product_workflow_response) return response.Response( status=ows_product_workflow_response.status_code, message=ows_product_workflow_response.json()) def update_release_correction(release_correction_id, correction_data): """Update an existing release correction. Args: release_correction_id (int): primary key of a release correction correction_data (dict): contains keys and their updated values """ ows_product_workflow_response = request.put( services.OWS_PRODUCT_WORKFLOW, '/correction/{}'.format(release_correction_id), json=correction_data, ) if ows_product_workflow_response.status_code != 200: error_handling.log_unexpected_response( services.OWS_PRODUCT_WORKFLOW, ows_product_workflow_response ) return response.create_fatal_response( message='cannot update a nonexistent release correction' ) return response.Response( status=ows_product_workflow_response.status_code, message=ows_product_workflow_response.json() ) def create_correction_details_records(release_correction_id, correction_data): """Create a collection of correction details for the given release correction. Args: release_correction_id (int): release correction id correction_data (dict): contents of the new correction details Returns: response.Response: status of post call and dictionary of results """ ows_product_workflow_response = request.post( services.OWS_PRODUCT_WORKFLOW, '/correction/{}/details'.format(release_correction_id), json=correction_data, ) if ows_product_workflow_response.status_code not in [201, 400]: error_handling.log_unexpected_response( services.OWS_PRODUCT_WORKFLOW, ows_product_workflow_response) return response.create_fatal_response( message='error saving correction details') return response.Response( status=ows_product_workflow_response.status_code, message=ows_product_workflow_response.json()) def is_product_checked_out_by_another_user(*, product_id, requesting_orchard_user_id=''): """Check if a product is checked out by a user other than the requesting user. This check is only used when updating a submitted product, ie a product with a status of transfer_to_content. Args: product_id (int): ID of the product to check. requesting_orchard_user_id (str): ID of the user making the request. Returns: bool: whether product is checked out. """ release_approval_response = get_last_release_approval_queue(product_id) release_approval_message = release_approval_response.message if not release_approval_response or not release_approval_message: return False release_approval_status = release_approval_message.get('status') checked_out_by_orchard_user_id = f"oa:{release_approval_message.get('checked_out_by', '')}" return ( release_approval_status == product_statuses.CHECKED_OUT and checked_out_by_orchard_user_id != requesting_orchard_user_id ) def product_submission(product_id, account_type, account_id, identity_id=''): """Create a collection of correction details for the given release correction. Args: product_id (int): id of the product to update. account_type (str): the user account type in the header. account_id (int): the user account id in the header. Returns: response.Response: status of post call and dictionary of results """ submission_data = { 'error_correction_flag': True, 'account_type': account_type, 'account_id': account_id, 'identity_id': identity_id or '', } ows_product_workflow_response = request.post( services.OWS_PRODUCT_WORKFLOW, '/product/{}/submission'.format(product_id), json=submission_data, ) if ows_product_workflow_response.status_code not in [200, 201]: error_handling.log_unexpected_response( services.OWS_PRODUCT_WORKFLOW, ows_product_workflow_response) return response.create_error_response( status=ows_product_workflow_response.status_code, code=error.OWS_PRODUCT_WORKFLOW_ERROR_CODE, message=ows_product_workflow_response.text) try: info_body = ows_product_workflow_response.json() except requests.exceptions.JSONDecodeError: return None return response.Response(message=info_body, status=200) def product_unsubmission(product_id, account_id, account_type): """Delete the latest release approval queue. Args: product_id (int): id of the product to update. account_type (str): the user account type in the header. account_id (int): the user account id in the header. Returns: response.Response: status of post call and dictionary of results """ submission_data = { 'account_type': account_type, 'account_id': account_id, } ows_product_workflow_response = request.post( services.OWS_PRODUCT_WORKFLOW, '/product/{}/unsubmit'.format(product_id), json=submission_data, ) if ows_product_workflow_response.status_code != 200: error_handling.log_unexpected_response( services.OWS_PRODUCT_WORKFLOW, ows_product_workflow_response) return response.create_error_response( status=ows_product_workflow_response.status_code, code=error.OWS_PRODUCT_WORKFLOW_ERROR_CODE, message=ows_product_workflow_response.json()) info_body = ows_product_workflow_response.json() return response.Response(message=info_body, status=200)