Skip to content

Commit b5f8dfc

Browse files
authored
Merge branch 'master' into master
2 parents 169ccc9 + 8001412 commit b5f8dfc

File tree

158 files changed

+30343
-862
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+30343
-862
lines changed

Diff for: bunsen/bunsen-avro/src/main/java/com/cerner/bunsen/avro/AvroConverter.java

+82-9
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@
77
import com.cerner.bunsen.definitions.HapiConverter;
88
import com.cerner.bunsen.definitions.HapiConverter.HapiObjectConverter;
99
import com.cerner.bunsen.definitions.StructureDefinitions;
10+
import com.cerner.bunsen.exception.ProfileException;
11+
import com.google.common.base.Preconditions;
12+
import java.util.ArrayList;
1013
import java.util.Collections;
1114
import java.util.HashMap;
15+
import java.util.Iterator;
1216
import java.util.List;
1317
import java.util.Map;
1418
import java.util.Map.Entry;
1519
import java.util.stream.Collectors;
1620
import org.apache.avro.Schema;
1721
import org.apache.avro.Schema.Field;
1822
import org.apache.avro.generic.IndexedRecord;
23+
import org.apache.commons.collections.CollectionUtils;
1924
import org.hl7.fhir.instance.model.api.IBaseResource;
2025

2126
/** Converter to change HAPI objects into Avro structures and vice versa. */
@@ -27,7 +32,6 @@ public class AvroConverter {
2732

2833
private AvroConverter(
2934
HapiConverter<Schema> hapiToAvroConverter, RuntimeResourceDefinition... resources) {
30-
3135
this.hapiToAvroConverter = hapiToAvroConverter;
3236
this.avroToHapiConverter = (HapiObjectConverter) hapiToAvroConverter.toHapiConverter(resources);
3337
}
@@ -37,7 +41,8 @@ private static AvroConverter visitResource(
3741
StructureDefinitions structureDefinitions,
3842
String resourceTypeUrl,
3943
List<String> containedResourceTypeUrls,
40-
Map<String, HapiConverter<Schema>> compositeConverters) {
44+
Map<String, HapiConverter<Schema>> compositeConverters,
45+
int recursiveDepth) {
4146

4247
FhirVersionEnum fhirVersion = context.getVersion().getVersion();
4348

@@ -58,7 +63,10 @@ private static AvroConverter visitResource(
5863

5964
DefinitionToAvroVisitor visitor =
6065
new DefinitionToAvroVisitor(
61-
structureDefinitions.conversionSupport(), basePackage, compositeConverters);
66+
structureDefinitions.conversionSupport(),
67+
basePackage,
68+
compositeConverters,
69+
recursiveDepth);
6270

6371
HapiConverter<Schema> converter =
6472
structureDefinitions.transform(visitor, resourceTypeUrl, containedResourceTypeUrls);
@@ -97,7 +105,7 @@ private static AvroConverter visitResource(
97105
* @return a list of Avro schemas
98106
*/
99107
public static List<Schema> generateSchemas(
100-
FhirContext context, Map<String, List<String>> resourceTypeUrls) {
108+
FhirContext context, Map<String, List<String>> resourceTypeUrls, int recursiveDepth) {
101109

102110
StructureDefinitions structureDefinitions = StructureDefinitions.create(context);
103111

@@ -110,7 +118,8 @@ public static List<Schema> generateSchemas(
110118
structureDefinitions,
111119
resourceTypeUrlEntry.getKey(),
112120
resourceTypeUrlEntry.getValue(),
113-
converters);
121+
converters,
122+
recursiveDepth);
114123
}
115124

116125
return converters.values().stream()
@@ -126,11 +135,40 @@ public static List<Schema> generateSchemas(
126135
*
127136
* @param context the FHIR context
128137
* @param resourceTypeUrl the URL of the resource type
138+
* @param recursiveDepth the maximum recursive depth to stop when converting a FHIR
139+
* StructureDefinition to an Avro schema.
129140
* @return an Avro converter instance.
130141
*/
131-
public static AvroConverter forResource(FhirContext context, String resourceTypeUrl) {
142+
public static AvroConverter forResource(
143+
FhirContext context, String resourceTypeUrl, int recursiveDepth) {
132144

133-
return forResource(context, resourceTypeUrl, Collections.emptyList());
145+
return forResource(context, resourceTypeUrl, Collections.emptyList(), recursiveDepth);
146+
}
147+
148+
/**
149+
* Similar to {@link #forResource(FhirContext, String, int)} this method returns an Avro
150+
* converter, but the returned Avro converter is a union of all the converters for the given
151+
* resourceTypeUrls, the union is formed by merging all the fields in each converter.
152+
*
153+
* @param context the FHIR context
154+
* @param resourceTypeUrls the list of resource type profile urls. The resourceTypeUrl can either
155+
* be a relative URL for a base resource (e.g., "Condition" or "Observation"), or a URL
156+
* identifying the structure definition for a given profile, such as
157+
* "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient".
158+
* @param recursiveDepth the maximum recursive depth to stop when converting a FHIR
159+
* StructureDefinition to an Avro schema.
160+
* @return the merged Avro converter
161+
*/
162+
public static AvroConverter forResources(
163+
FhirContext context, List<String> resourceTypeUrls, int recursiveDepth)
164+
throws ProfileException {
165+
List<AvroConverter> avroConverters = new ArrayList<>();
166+
for (String resourceTypeUrl : resourceTypeUrls) {
167+
AvroConverter avroConverter =
168+
forResource(context, resourceTypeUrl, Collections.emptyList(), recursiveDepth);
169+
avroConverters.add(avroConverter);
170+
}
171+
return mergeAvroConverters(avroConverters, context);
134172
}
135173

136174
/**
@@ -145,15 +183,25 @@ public static AvroConverter forResource(FhirContext context, String resourceType
145183
* @param context the FHIR context
146184
* @param resourceTypeUrl the URL of the resource type
147185
* @param containedResourceTypeUrls the list of URLs of contained resource types
186+
* @param recursiveDepth the maximum recursive depth to stop when converting a FHIR
187+
* StructureDefinition to an Avro schema.
148188
* @return an Avro converter instance.
149189
*/
150190
public static AvroConverter forResource(
151-
FhirContext context, String resourceTypeUrl, List<String> containedResourceTypeUrls) {
191+
FhirContext context,
192+
String resourceTypeUrl,
193+
List<String> containedResourceTypeUrls,
194+
int recursiveDepth) {
152195

153196
StructureDefinitions structureDefinitions = StructureDefinitions.create(context);
154197

155198
return visitResource(
156-
context, structureDefinitions, resourceTypeUrl, containedResourceTypeUrls, new HashMap<>());
199+
context,
200+
structureDefinitions,
201+
resourceTypeUrl,
202+
containedResourceTypeUrls,
203+
new HashMap<>(),
204+
recursiveDepth);
157205
}
158206

159207
/**
@@ -196,4 +244,29 @@ public Schema getSchema() {
196244
public String getResourceType() {
197245
return hapiToAvroConverter.getElementType();
198246
}
247+
248+
/**
249+
* Merges all the given list of avroConverters to create a single AvroConverter which is a union
250+
* of all the fields in the list of avroConverters
251+
*/
252+
private static AvroConverter mergeAvroConverters(
253+
List<AvroConverter> avroConverters, FhirContext context) throws ProfileException {
254+
Preconditions.checkArgument(
255+
!CollectionUtils.isEmpty(avroConverters), "AvroConverter list cannot be empty for merging");
256+
Iterator<AvroConverter> iterator = avroConverters.iterator();
257+
AvroConverter mergedConverter = iterator.next();
258+
while (iterator.hasNext()) {
259+
mergedConverter = mergeAvroConverters(mergedConverter, iterator.next(), context);
260+
}
261+
return mergedConverter;
262+
}
263+
264+
private static AvroConverter mergeAvroConverters(
265+
AvroConverter left, AvroConverter right, FhirContext context) throws ProfileException {
266+
HapiConverter<Schema> mergedConverter =
267+
left.hapiToAvroConverter.merge(right.hapiToAvroConverter);
268+
RuntimeResourceDefinition[] resources = new RuntimeResourceDefinition[1];
269+
resources[0] = context.getResourceDefinition(mergedConverter.getElementType());
270+
return new AvroConverter(mergedConverter, resources);
271+
}
199272
}

0 commit comments

Comments
 (0)