from flask_restful import Resource, request from flask_restful import current_app from requests.auth import HTTPBasicAuth from helpers.Error import ImportApiError from datetime import datetime import requests import json class WriteJobResultToDrupal(Resource): def post(self, job_drupal_uuid, job_log_drupal_uuid): """ Write the job summary to Drupal job log (in field_summary) --- tags: - reporting parameters: - in: path name: job_drupal_uuid required: true description: job log uuid type: string - in: path name: job_log_drupal_uuid required: true description: job report log uuid type: string - in: body name: body required: true schema: properties: sessionId: type: string example: "550e8400-e29b-11d4-a716-446655440000" step: type: string example: "media-metadata-extractor" total: type: integer example: 468 success: type: integer example: 413 ignore: type: integer example: 0 warning: type: integer example: 455 fatal: type: integer example: 0 earliest: type: string example: "2021-03-08T14:02:23.232" latest: type: string example: "latest" elapsedTime: type: string example: "00:03:11.219" recordSetId: type: string example: "fss-001" institutionId: type: string example: "fss" messageId: type: string example: "1b7d8224-451a-4afb-b5d2-6537acb74051" previousMessageId: type: string example: "04543477-3bb5-4d01-a318-52ded1ce5e1c" version: type: string example: "3" responses: 200: description: It was successful 404: description: No log result with such a uuid 500: description: There was a problem """ try: body = request.json current_app.logger.debug("report data: " + json.dumps(body, indent=2)) fatal = body['fatal'] status = 'FAILED' if fatal == 0: status = 'SUCCESS' return write_results(job_drupal_uuid, job_log_drupal_uuid, status, body) except ImportApiError as e: return {'error': e.message}, 500 def write_results(job_drupal_uuid, job_log_drupal_uuid, status, report): current_app.logger.debug("job-uuid to write: " + job_drupal_uuid) current_app.logger.debug("job-report-uuid to write: " + job_log_drupal_uuid) current_app.logger.debug("report to write: " + json.dumps(report, indent=2)) headers = { 'Content-Type': 'application/vnd.api+json', 'Accept': 'application/vnd.api+json', 'X-API-Key': current_app.config['drupal-api-key'] } user = current_app.config['drupal-user'] password = current_app.config['drupal-password'] auth = HTTPBasicAuth(user, password) # read "status" and "message" from log_result previous_status = '' previous_report = '' previous_report_json = '' step = '' try: getUrl = current_app.config['drupal-api-url'] + \ '/jsonapi/node/log_result/' + job_log_drupal_uuid response = requests.get(getUrl, headers=headers, auth=auth) logResult = response.json()['data'] previous_status = logResult['attributes']['field_status'] previous_report = logResult['attributes']['field_message'] except requests.exceptions.RequestException: message = 'It was not possible to read form the Drupal API:' + getUrl +\ '\nresponse: ' + response current_app.logger.error(message) raise ImportApiError(message) if previous_status == 'FAILED': status = previous_status if previous_report is None: previous_report_json = {} else: previous_report_json = json.loads(previous_report) step = report['step'] previous_report_json[step] = report reportString = json.dumps(previous_report) # update values in drupal: patchCalls = {} patchUrl = current_app.config['drupal-api-url'] + \ '/jsonapi/node/import_process/' + job_drupal_uuid patchData = { "data": { "id": job_drupal_uuid, "type": "node--import_process", "attributes": { "field_state": 0 } } } patchCalls[patchUrl] = patchData patchUrl = current_app.config['drupal-api-url'] + \ '/jsonapi/node/log_result/' + job_log_drupal_uuid patchData = { "data": { "id": job_log_drupal_uuid, "type": "node--job_result", "attributes": { "field_end_date": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S+00:00"), "field_status": status, "field_message": reportString } } } patchCalls[patchUrl] = patchData returnVal = {'message': ''} for patchCall in patchCalls: url = patchCall data = patchCalls[patchCall] try: response = requests.patch( url, headers=headers, data=json.dumps(data) ) except requests.exceptions.RequestException: message = "It was not possible to write to Drupal API \ via the following url " + url current_app.logger.error(message) raise ImportApiError(message) if response.status_code == 200: current_app.logger.debug('Updated: ' + url) returnVal['message'] += 'Updated: ' + url + '\n' elif response.status_code == 403: message = "Not authorized to write to: " + url current_app.logger.error(message) raise ImportApiError(message) elif response.status_code == 404: message = 'Not Found: ' + url current_app.logger.error(message) raise ImportApiError(message) elif response.status_code == 500: message = 'There was an internal server error for ' + url + ': ' + str(response) +\ '. Check the logs for details.' current_app.logger.error(message) raise ImportApiError(message) else: message = "Unknown response status code for drupal api for url " + url current_app.logger.error(message) raise ImportApiError(message) return returnVal