Skip to content

Commit 00f7565

Browse files
authored
BB2-3865: Added v3 urls and waffle switch (#1333)
* Added v3 urls and waffle switch * Add flag to test flags. Add v3 language in routing * Split version logic * v3 and v2 as v2 for now * Expanded scope definitions for v3 * Refactor version checks * Live waffle switch
1 parent 2d2e5c5 commit 00f7565

File tree

6 files changed

+89
-18
lines changed

6 files changed

+89
-18
lines changed

apps/accounts/fixtures/scopes.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"slug": "patient/Patient.read",
1616
"group": 5,
1717
"description": "Patient FHIR Resource",
18-
"protected_resources": "[\n [\n \"GET\",\n \"/v[12]/fhir/Patient[/]?$\"\n ],\n [\n \"GET\",\n \"/v[12]/fhir/Patient[/?].*$\"\n ]\n]",
18+
"protected_resources": "[\n [\n \"GET\",\n \"/v[123]/fhir/Patient[/]?$\"\n ],\n [\n \"GET\",\n \"/v[123]/fhir/Patient[/?].*$\"\n ]\n]",
1919
"default": "True"
2020
}
2121
},
@@ -27,7 +27,7 @@
2727
"slug": "profile",
2828
"group": 5,
2929
"description": "OIDC userinfo endpoint /connect/userinfo",
30-
"protected_resources": "[\n [\n \"GET\",\n \"/v[12]/connect/userinfo.*$\"\n ]\n]",
30+
"protected_resources": "[\n [\n \"GET\",\n \"/v[123]/connect/userinfo.*$\"\n ]\n]",
3131
"default": "True"
3232
}
3333
},
@@ -39,7 +39,7 @@
3939
"slug": "patient/ExplanationOfBenefit.read",
4040
"group": 5,
4141
"description": "ExplanationOfBenefit FHIR Resource",
42-
"protected_resources": "[\n [\n \"GET\",\n \"/v[12]/fhir/ExplanationOfBenefit[/]?$\"\n ],\n [\n \"GET\",\n \"/v[12]/fhir/ExplanationOfBenefit[/?].*$\"\n ]\n]",
42+
"protected_resources": "[\n [\n \"GET\",\n \"/v[123]/fhir/ExplanationOfBenefit[/]?$\"\n ],\n [\n \"GET\",\n \"/v[123]/fhir/ExplanationOfBenefit[/?].*$\"\n ]\n]",
4343
"default": "True"
4444
}
4545
},
@@ -51,7 +51,7 @@
5151
"slug": "patient/Coverage.read",
5252
"group": 5,
5353
"description": "Coverage FHIR Resource",
54-
"protected_resources": "[\n [\n \"GET\",\n \"/v[12]/fhir/Coverage[/]?$\"\n ],\n [\n \"GET\",\n \"/v[12]/fhir/Coverage[/?].*$\"\n ]\n]",
54+
"protected_resources": "[\n [\n \"GET\",\n \"/v[123]/fhir/Coverage[/]?$\"\n ],\n [\n \"GET\",\n \"/v[123]/fhir/Coverage[/?].*$\"\n ]\n]",
5555
"default": "True"
5656
}
5757
},
@@ -75,7 +75,7 @@
7575
"slug": "token_introspect",
7676
"group": 5,
7777
"description": "Allow an app to introspect a user's tokens.",
78-
"protected_resources": "[[\"POST\", \"/v[12]/o/introspect\"]]",
78+
"protected_resources": "[[\"POST\", \"/v[123]/o/introspect\"]]",
7979
"default": "False"
8080
}
8181
},
@@ -99,7 +99,7 @@
9999
"slug": "patient/Patient.r",
100100
"group": 5,
101101
"description": "Patient FHIR Resource",
102-
"protected_resources": "[\n \n [\n \"GET\",\n \"/v[12]/fhir/Patient[/?].*$\"\n ]\n]",
102+
"protected_resources": "[\n \n [\n \"GET\",\n \"/v[123]/fhir/Patient[/?].*$\"\n ]\n]",
103103
"default": "True"
104104
}
105105
},
@@ -111,7 +111,7 @@
111111
"slug": "patient/Patient.s",
112112
"group": 5,
113113
"description": "Patient FHIR Resource",
114-
"protected_resources": "[\n [\n \"GET\",\n \"/v[12]/fhir/Patient[/]?$\"\n ]\n]",
114+
"protected_resources": "[\n [\n \"GET\",\n \"/v[123]/fhir/Patient[/]?$\"\n ]\n]",
115115
"default": "True"
116116
}
117117
},
@@ -123,7 +123,7 @@
123123
"slug": "patient/Patient.rs",
124124
"group": 5,
125125
"description": "Patient FHIR Resource",
126-
"protected_resources": "[\n [\n \"GET\",\n \"/v[12]/fhir/Patient[/]?$\"\n ],\n [\n \"GET\",\n \"/v[12]/fhir/Patient[/?].*$\"\n ]\n]",
126+
"protected_resources": "[\n [\n \"GET\",\n \"/v[123]/fhir/Patient[/]?$\"\n ],\n [\n \"GET\",\n \"/v[123]/fhir/Patient[/?].*$\"\n ]\n]",
127127
"default": "True"
128128
}
129129
},
@@ -135,7 +135,7 @@
135135
"slug": "patient/ExplanationOfBenefit.r",
136136
"group": 5,
137137
"description": "ExplanationOfBenefit FHIR Resource",
138-
"protected_resources": "[\n \n [\n \"GET\",\n \"/v[12]/fhir/ExplanationOfBenefit[/?].*$\"\n ]\n]",
138+
"protected_resources": "[\n \n [\n \"GET\",\n \"/v[123]/fhir/ExplanationOfBenefit[/?].*$\"\n ]\n]",
139139
"default": "True"
140140
}
141141
},
@@ -147,7 +147,7 @@
147147
"slug": "patient/ExplanationOfBenefit.s",
148148
"group": 5,
149149
"description": "ExplanationOfBenefit FHIR Resource",
150-
"protected_resources": "[\n [\n \"GET\",\n \"/v[12]/fhir/ExplanationOfBenefit[/]?$\"\n ]\n]",
150+
"protected_resources": "[\n [\n \"GET\",\n \"/v[123]/fhir/ExplanationOfBenefit[/]?$\"\n ]\n]",
151151
"default": "True"
152152
}
153153
},
@@ -159,7 +159,7 @@
159159
"slug": "patient/ExplanationOfBenefit.rs",
160160
"group": 5,
161161
"description": "ExplanationOfBenefit FHIR Resource",
162-
"protected_resources": "[\n [\n \"GET\",\n \"/v[12]/fhir/ExplanationOfBenefit[/]?$\"\n ],\n [\n \"GET\",\n \"/v[12]/fhir/ExplanationOfBenefit[/?].*$\"\n ]\n]",
162+
"protected_resources": "[\n [\n \"GET\",\n \"/v[123]/fhir/ExplanationOfBenefit[/]?$\"\n ],\n [\n \"GET\",\n \"/v[123]/fhir/ExplanationOfBenefit[/?].*$\"\n ]\n]",
163163
"default": "True"
164164
}
165165
},
@@ -171,7 +171,7 @@
171171
"slug": "patient/Coverage.r",
172172
"group": 5,
173173
"description": "Coverage FHIR Resource",
174-
"protected_resources": "[\n \n [\n \"GET\",\n \"/v[12]/fhir/Coverage[/?].*$\"\n ]\n]",
174+
"protected_resources": "[\n \n [\n \"GET\",\n \"/v[123]/fhir/Coverage[/?].*$\"\n ]\n]",
175175
"default": "True"
176176
}
177177
},
@@ -183,7 +183,7 @@
183183
"slug": "patient/Coverage.s",
184184
"group": 5,
185185
"description": "Coverage FHIR Resource",
186-
"protected_resources": "[\n [\n \"GET\",\n \"/v[12]/fhir/Coverage[/]?$\"\n ]\n]",
186+
"protected_resources": "[\n [\n \"GET\",\n \"/v[123]/fhir/Coverage[/]?$\"\n ]\n]",
187187
"default": "True"
188188
}
189189
},
@@ -195,7 +195,7 @@
195195
"slug": "patient/Coverage.rs",
196196
"group": 5,
197197
"description": "Coverage FHIR Resource",
198-
"protected_resources": "[\n [\n \"GET\",\n \"/v[12]/fhir/Coverage[/]?$\"\n ],\n [\n \"GET\",\n \"/v[12]/fhir/Coverage[/?].*$\"\n ]\n]",
198+
"protected_resources": "[\n [\n \"GET\",\n \"/v[123]/fhir/Coverage[/]?$\"\n ],\n [\n \"GET\",\n \"/v[123]/fhir/Coverage[/?].*$\"\n ]\n]",
199199
"default": "True"
200200
}
201201
},

apps/capabilities/management/commands/create_blue_button_scopes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
logger = logging.getLogger(bb2logging.HHS_SERVER_LOGNAME_FMT.format(__name__))
1313

14-
fhir_prefix = "/v[12]/fhir/"
14+
fhir_prefix = "/v[123]/fhir/"
1515

1616

1717
def create_group(name="BlueButton"):

apps/core/management/commands/create_test_feature_switches.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
("splunk_monitor", False, "This is used in other environments to ensure splunk forwarder is running."),
1717
("testclient_v2", True, "This enables the v2 auth links in the test client"),
1818
("wellknown_applications", True, "This enables the /.well-known/applications end-point. Active in prod, but not in sbx/test."),
19+
("v3_endpoints", True, "This enables v3 endpoints."),
1920
("bfd_v3_connectathon", True, "This enables the bfd v3 features for connectathon demo"),
2021
)
2122

apps/fhir/bluebutton/v3/urls.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from django.urls import re_path
2+
from django.contrib import admin
3+
from waffle.decorators import waffle_switch
4+
5+
from apps.fhir.bluebutton.views.read import (
6+
ReadViewCoverage,
7+
ReadViewExplanationOfBenefit,
8+
ReadViewPatient,
9+
)
10+
from apps.fhir.bluebutton.views.search import (
11+
SearchViewCoverage,
12+
SearchViewExplanationOfBenefit,
13+
SearchViewPatient,
14+
)
15+
16+
admin.autodiscover()
17+
18+
urlpatterns = [
19+
# Patient ReadView
20+
re_path(
21+
r"Patient/(?P<resource_id>[^/]+)",
22+
waffle_switch("v3_endpoints")(ReadViewPatient.as_view(version=3)),
23+
name="bb_oauth_fhir_patient_read_or_update_or_delete_v3",
24+
),
25+
# Patient SearchView
26+
re_path(
27+
r"Patient[/]?",
28+
waffle_switch("v3_endpoints")(SearchViewPatient.as_view(version=3)),
29+
name="bb_oauth_fhir_patient_search_v3",
30+
),
31+
# Coverage ReadView
32+
re_path(
33+
r"Coverage/(?P<resource_id>[^/]+)",
34+
waffle_switch("v3_endpoints")(ReadViewCoverage.as_view(version=3)),
35+
name="bb_oauth_fhir_coverage_read_or_update_or_delete_v3",
36+
),
37+
# Coverage SearchView
38+
re_path(
39+
r"Coverage[/]?",
40+
waffle_switch("v3_endpoints")(SearchViewCoverage.as_view(version=3)),
41+
name="bb_oauth_fhir_coverage_search_v3",
42+
),
43+
# EOB ReadView
44+
re_path(
45+
r"ExplanationOfBenefit/(?P<resource_id>[^/]+)",
46+
waffle_switch("v3_endpoints")(ReadViewExplanationOfBenefit.as_view(version=3)),
47+
name="bb_oauth_fhir_eob_read_or_update_or_delete_v3",
48+
),
49+
# EOB SearchView
50+
re_path(
51+
r"ExplanationOfBenefit[/]?",
52+
waffle_switch("v3_endpoints")(SearchViewExplanationOfBenefit.as_view(version=3)),
53+
name="bb_oauth_fhir_eob_search_v3",
54+
),
55+
]

apps/fhir/bluebutton/views/generic.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,28 @@ def fetch_data(self, request, resource_type, *args, **kwargs):
151151
req.headers["BlueButton-Application"] = quote(req.headers.get("BlueButton-Application"))
152152

153153
prepped = s.prepare_request(req)
154+
155+
if self.version == 1:
156+
api_ver_str = 'v1'
157+
elif self.version == 2:
158+
api_ver_str = 'v2'
159+
# v3 uses v2 for now
160+
elif self.version == 3:
161+
api_ver_str = 'v2'
162+
# defaults to v3
163+
else:
164+
logger.debug('Unexpected version number %d, defaulting to v2' % self.version)
165+
api_ver_str = 'v2'
166+
154167
# Send signal
155-
pre_fetch.send_robust(FhirDataView, request=req, auth_request=request, api_ver='v2' if self.version == 2 else 'v1')
168+
pre_fetch.send_robust(FhirDataView, request=req, auth_request=request, api_ver=api_ver_str)
156169
r = s.send(
157170
prepped,
158171
cert=backend_connection.certs(crosswalk=request.crosswalk),
159172
timeout=resource_router.wait_time,
160173
verify=FhirServerVerify(crosswalk=request.crosswalk))
161174
# Send signal
162-
post_fetch.send_robust(FhirDataView, request=prepped, auth_request=request,
163-
response=r, api_ver='v2' if self.version == 2 else 'v1')
175+
post_fetch.send_robust(FhirDataView, request=prepped, auth_request=request, response=r, api_ver=api_ver_str)
164176
response = build_fhir_response(request._request, target_url, request.crosswalk, r=r, e=None)
165177

166178
# BB2-128

hhs_oauth_server/urls.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from rest_framework import status
55
from django.urls import include, path, re_path
66
from django.contrib import admin
7+
78
from apps.accounts.views.oauth2_profile import openidconnect_userinfo
89
from apps.fhir.bluebutton.views.home import fhir_conformance, fhir_conformance_v2
910
from apps.wellknown.views.openid import smart_configuration
@@ -37,6 +38,7 @@
3738
path("v2/fhir/.well-known/smart-configuration", smart_configuration, name="smart_configuration"),
3839
path("v2/fhir/metadata", fhir_conformance_v2, name="fhir_conformance_metadata_v2"),
3940
path("v2/fhir/", include("apps.fhir.bluebutton.v2.urls")),
41+
path("v3/fhir/", include("apps.fhir.bluebutton.v3.urls")),
4042
path("v2/o/", include("apps.dot_ext.v2.urls")),
4143
path("v2/o/", include("apps.authorization.v2.urls")),
4244
path("docs/", include("apps.docs.urls")),
@@ -46,6 +48,7 @@
4648
path("akamai/testobject", testobject, name="akamai_testobject"),
4749
]
4850

51+
4952
# If running in local development, add the media and static urls:
5053
if settings.IS_MEDIA_URL_LOCAL is True:
5154
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

0 commit comments

Comments
 (0)