Skip to content

Commit

Permalink
OpenConceptLab/ocl_issues#1761 Add FHIR xml support
Browse files Browse the repository at this point in the history
  • Loading branch information
rkorytkowski committed May 1, 2024
1 parent 5acde79 commit e04e09a
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 5 deletions.
4 changes: 4 additions & 0 deletions core/common/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
wrapper = FileWrapper(temp)
temp.seek(0)
return wrapper


class FhirRenderer(JSONRenderer):
media_type = 'application/fhir+json'
38 changes: 33 additions & 5 deletions core/middlewares/middlewares.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import logging
import time

from django.http import HttpResponseNotFound
import requests
from django.http import HttpResponseNotFound, HttpRequest, HttpResponse
from request_logging.middleware import LoggingMiddleware

from core.common.constants import VERSION_HEADER, REQUEST_USER_HEADER, RESPONSE_TIME_HEADER, REQUEST_URL_HEADER, \
Expand Down Expand Up @@ -83,14 +84,16 @@ def __call__(self, request):

class FhirMiddleware(BaseMiddleware):
"""
It is used to expose FHIR endpoints under FHIR subdomain only. If FHIR is not deployed under a dedicated subdomain
then FHIR_SUBDOMAIN environment variable should be empty.
It is used to expose FHIR endpoints under FHIR subdomain only and convert content from xml to json.
If FHIR is not deployed under a dedicated subdomain then FHIR_SUBDOMAIN environment variable should be empty.
"""

def __call__(self, request):
absolute_uri = request.build_absolute_uri()

from django.conf import settings
if settings.FHIR_SUBDOMAIN:
uri = request.build_absolute_uri().split('/')
uri = absolute_uri.split('/')
domain = uri[2] if len(uri) > 2 else ''
is_fhir_domain = domain.startswith(settings.FHIR_SUBDOMAIN + '.')
resource_type = uri[5] if len(uri) > 5 else None
Expand All @@ -104,5 +107,30 @@ def __call__(self, request):
elif is_fhir_resource:
return HttpResponseNotFound()

response = self.get_response(request)
if settings.FHIR_VALIDATOR_URL and ('/CodeSystem/' in absolute_uri or '/ValueSet/' in absolute_uri or
'/ConceptMap' in absolute_uri):
accept_content_type = request.headers.get('Accept')
content_type = request.headers.get('Content-Type')

if content_type.startswith('application/xml') or content_type.startswith('application/fhir+xml'):
request.META['CONTENT_TYPE'] = "application/json"
if request.method == 'POST' or request.method == 'PUT':
json_request = requests.post(settings.FHIR_VALIDATOR_URL +
'/convert?version=4.0&type=xml&toType=json', data=request.body)
request._body = json_request

if accept_content_type.startswith('application/xml') or \
accept_content_type.startswith('application/fhir+xml'):
request.META['HTTP_ACCEPT'] = "application/json"

response = self.get_response(request)

if accept_content_type.startswith('application/xml') or \
accept_content_type.startswith('application/fhir+xml'):
xml_response = requests.post(settings.FHIR_VALIDATOR_URL + '/convert?version=4.0&type=json&toType=xml',
data=response.content)
response = HttpResponse(xml_response, content_type=accept_content_type)
else:
response = self.get_response(request)

return response
3 changes: 3 additions & 0 deletions core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'core.common.renderers.ZippedJSONRenderer',
'core.common.renderers.FhirRenderer'
),
'COERCE_DECIMAL_TO_STRING': False,
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
Expand Down Expand Up @@ -337,6 +338,8 @@
API_SUPERUSER_PASSWORD = os.environ.get('API_SUPERUSER_PASSWORD', 'Root123') # password for ocladmin superuser
API_SUPERUSER_TOKEN = os.environ.get('API_SUPERUSER_TOKEN', '891b4b17feab99f3ff7e5b5d04ccc5da7aa96da6')

FHIR_VALIDATOR_URL = os.environ.get('FHIR_VALIDATOR_URL', None)

# Redis
REDIS_CONNECTION_OPTIONS = {
'socket_timeout': 5.0,
Expand Down
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,16 @@ services:
- AZURE_STORAGE_ACCOUNT_NAME
- AZURE_STORAGE_CONTAINER_NAME
- AZURE_STORAGE_CONNECTION_STRING
- FHIR_VALIDATOR_URL=${FHIR_VALIDATOR_URL-http://fhir_validator:3500}
healthcheck:
test: "curl --silent --fail http://localhost:8000/version/ || exit 1"
fhir_validator:
image: openconceptlab/validator-wrapper:1.0.53-1deb1a4b
restart: "always"
ports:
- 3500:3500
healthcheck:
test: "curl --silent --fail http://localhost:3500/ || exit 1"
celery:
image: openconceptlab/oclapi2:${ENVIRONMENT-production}
command: ["bash", "-c", "CELERY_WORKER_NAME=default ./start_celery_worker.sh -P prefork -Q default -c 2"]
Expand Down

0 comments on commit e04e09a

Please sign in to comment.