def fetch_items(self, Model): # Try to fetch the requested resource(s) try: res = Model.get(query=self.query) return res except (MappingValidationError, FHIRValidationError) as e: raise OperationError( severity="error", code="not-found", diagnostics="{}".format(e), status_code=404, ) except AuthorizationError as e: raise OperationError( severity="error", code="security", diagnostics="{}".format(e.auditEvent.as_json()), status_code=403, ) except Exception as e: diag = "{}".format(e) if settings.DEBUG: tb = traceback.format_exc() diag += " {}".format(tb) raise OperationError( severity="error", code="exception", diagnostics="{}".format(diag), status_code=500, )
def import_models(self): try: models = import_models() except ConfigurationError: raise OperationError( severity="error", code="exception", diagnostics="The server is improprly configured", status_code=500, ) return models
def parse_url(self, url, context=None): try: self.query = parse_url(url) self.query.context = context register_request_context(self.query) except QueryValidationError as e: raise OperationError( severity="error", code="invalid", diagnostics="{}".format(e), status_code=400, )
def request_body_to_resource(self, Resource): # Validate the incoming json try: resource = Resource(self.body) return resource except Exception as e: raise OperationError( severity="error", code="value", diagnostics="{}".format(e), status_code=404, )
def handle(self, url, query_context=None): try: self.parse_url(url, query_context) # Authorize the request if implemented self._audit_request(self.query) # Import the model mappings models = self.import_models() # Get the Resource Model = self.get_resource(models) try: instance = Model._get_item_from_pk(self.query.resourceId) except DoesNotExistError as e: raise OperationError( severity="error", code="not-found", diagnostics="{}/{} was not found on the server.".format( e.resource_type, e.pk ), status_code=404, ) Model._delete_item(instance) self.log_request( url=url, query=self.query, resource=instance, status=202, method="DELETE", ) except OperationError as e: self.log_request( url=url, query=getattr(self, "query", None), status=e.status_code, method="DELETE", OperationOutcome=e.to_fhir(), ) return e.to_fhir().as_json(), e.status_code return ( OperationOutcome( issue={ "severity": "information", "code": "informational", "details": {"text": "All ok"}, } ).as_json(), 200, )
def handle(self, url, body, query_context=None): try: self.body = body self.parse_url(url, query_context) self._audit_request(self.query) # Import the model mappings models = self.import_models() # Get the Model class Model = self.get_resource(models) try: instance = Model._get_item_from_pk(self.query.resourceId) except DoesNotExistError as e: raise OperationError( severity="error", code="not-found", diagnostics="{}/{} was not found on the server.".format( e.resource_type, e.pk ), status_code=404, ) from fhirbug.Fhir import resources # Get the Resource class Resource = self.get_resource(resources) # Validate the incoming json and instantiate the Fhir resource resource = self.request_body_to_resource(Resource) updated_resource = self.update(instance, resource) self.log_request( url=url, query=self.query, resource=updated_resource, status=202, method="PUT", request_body=getattr(self, "body", None), ) return updated_resource.to_fhir().as_json(), 202 except OperationError as e: self.log_request( url=url, query=getattr(self, "query", None), status=e.status_code, method="PUT", request_body=getattr(self, "body", None), OperationOutcome=e.to_fhir(), ) return e.to_fhir().as_json(), e.status_code
def get_resource(self, models): resource_name = self.query.resource or "" try: # TODO: handle mapper names different then the resource # Maybe a dict in the settings? Resource = getattr(models, resource_name) except AttributeError: raise OperationError( severity="error", code="not-found", diagnostics=f'Resource "{resource_name}" does not exist.', status_code=404, ) return Resource
def update(self, instance, resource): try: updated_resource = instance.update_from_resource(resource, query=self.query) except Exception as e: diag = "{}".format(e) if settings.DEBUG: tb = traceback.format_exc() diag += " {}".format(tb) raise OperationError( severity="error", code="invalid", diagnostics="{}".format(diag), status_code=422, ) return updated_resource
def _audit_request(self, query): if hasattr(self, "audit_request"): auditEvent = self.audit_request(query) # self.auditEvent.entity[0].detail.append( # {"type": "AuditOutcome", "valueString": auditEvent.outcome} # ) # self.auditEvent.entity[0].detail.append( # { # "type": "AuditDescription", # "valueString": getattr(auditEvent, "outcomeDesc", None), # } # ) if auditEvent.outcome != "0": raise OperationError( severity="error", code="security", diagnostics=getattr(auditEvent, "outcomeDesc", None), status_code=403, )