Skip to content

Commit

Permalink
OpenConceptLab/ocl_issues#495 added pagination for code system
Browse files Browse the repository at this point in the history
  • Loading branch information
Harsh Patel committed Dec 7, 2020
1 parent 597c493 commit de831ae
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ public OclFhirController(CodeSystemResourceProvider codeSystemResourceProvider,
}

@GetMapping(path = {"/orgs/{org}/CodeSystem/{id}"}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> getCodeSystemByOrg(@PathVariable(name = ORG) String org, @PathVariable(name = ID) String id) {
public ResponseEntity<String> getCodeSystemByOrg(@PathVariable(name = ORG) String org,
@PathVariable(name = ID) String id,
@RequestParam(name = PAGE, required = false) String page) {
if (isValid(page))
return handleSearchResource(CodeSystem.class, OWNER, formatOrg(org), ID, id, PAGE, page);
return handleSearchResource(CodeSystem.class, OWNER, formatOrg(org), ID, id);
}

Expand All @@ -50,7 +54,10 @@ public ResponseEntity<String> getCodeSystemByOrg(@PathVariable(name = ORG) Strin
produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> getCodeSystemVersionsByOrg(@PathVariable(name = ORG) String org,
@PathVariable(name = ID) String id,
@PathVariable(name = VERSION) Optional<String> version) {
@PathVariable(name = VERSION) Optional<String> version,
@RequestParam(name = PAGE, required = false) String page) {
if (isValid(page))
return handleSearchResource(CodeSystem.class, OWNER, formatOrg(org), ID, id, VERSION, version.orElse(ALL), PAGE, page);
return handleSearchResource(CodeSystem.class, OWNER, formatOrg(org), ID, id, VERSION, version.orElse(ALL));
}

Expand Down Expand Up @@ -95,7 +102,11 @@ public ResponseEntity<String> validateCodeSystemsByOrg(@PathVariable String org,
}

@GetMapping(path = {"/orgs/{org}/ValueSet/{id}"}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> getValueSetByOrg(@PathVariable String org, @PathVariable String id) {
public ResponseEntity<String> getValueSetByOrg(@PathVariable String org,
@PathVariable String id,
@RequestParam(name = PAGE, required = false) String page) {
if (isValid(page))
return handleSearchResource(ValueSet.class, OWNER, formatOrg(org), ID, id, PAGE, page);
return handleSearchResource(ValueSet.class, OWNER, formatOrg(org), ID, id);
}

Expand All @@ -104,7 +115,10 @@ public ResponseEntity<String> getValueSetByOrg(@PathVariable String org, @PathVa
produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> getValueSetVersionsByOrg(@PathVariable(name = ORG) String org,
@PathVariable(name = ID) String id,
@PathVariable(name = VERSION) Optional<String> version) {
@PathVariable(name = VERSION) Optional<String> version,
@RequestParam(name = PAGE, required = false) String page) {
if (isValid(page))
return handleSearchResource(ValueSet.class, OWNER, formatOrg(org), ID, id, VERSION, version.orElse(ALL), PAGE, page);
return handleSearchResource(ValueSet.class, OWNER, formatOrg(org), ID, id, VERSION, version.orElse(ALL));
}

Expand Down Expand Up @@ -160,7 +174,11 @@ public ResponseEntity<String> expandValueSetByOrg(@PathVariable String org, @Req
}

@GetMapping(path = {"/users/{user}/CodeSystem/{id}"}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> getCodeSystemByUser(@PathVariable String user, @PathVariable String id) {
public ResponseEntity<String> getCodeSystemByUser(@PathVariable String user,
@PathVariable String id,
@RequestParam(name = PAGE, required = false) String page) {
if (isValid(page))
return handleSearchResource(CodeSystem.class, OWNER, formatUser(user), ID, id, PAGE, page);
return handleSearchResource(CodeSystem.class, OWNER, formatUser(user), ID, id);
}

Expand All @@ -169,7 +187,10 @@ public ResponseEntity<String> getCodeSystemByUser(@PathVariable String user, @Pa
produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> getCodeSystemVersionsByUser(@PathVariable(name = USER) String user,
@PathVariable(name = ID) String id,
@PathVariable(name = VERSION) Optional<String> version) {
@PathVariable(name = VERSION) Optional<String> version,
@RequestParam(name = PAGE, required = false) String page) {
if (isValid(page))
return handleSearchResource(CodeSystem.class, OWNER, formatUser(user), ID, id, VERSION, version.orElse(ALL), PAGE, page);
return handleSearchResource(CodeSystem.class, OWNER, formatUser(user), ID, id, VERSION, version.orElse(ALL));
}

Expand Down Expand Up @@ -214,7 +235,11 @@ public ResponseEntity<String> validateCodeSystemsByUser(@PathVariable String use
}

@GetMapping(path = {"/users/{user}/ValueSet/{id}"}, produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> getValueSetByUser(@PathVariable String user, @PathVariable String id) {
public ResponseEntity<String> getValueSetByUser(@PathVariable String user,
@PathVariable String id,
@RequestParam(name = PAGE, required = false) String page) {
if (isValid(page))
return handleSearchResource(ValueSet.class, OWNER, formatUser(user), ID, id, PAGE, page);
return handleSearchResource(ValueSet.class, OWNER, formatUser(user), ID, id);
}

Expand All @@ -223,7 +248,10 @@ public ResponseEntity<String> getValueSetByUser(@PathVariable String user, @Path
produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> getValueSetVersionsByUser(@PathVariable(name = USER) String user,
@PathVariable(name = ID) String id,
@PathVariable(name = VERSION) Optional<String> version) {
@PathVariable(name = VERSION) Optional<String> version,
@RequestParam(name = PAGE, required = false) String page) {
if (isValid(page))
return handleSearchResource(ValueSet.class, OWNER, formatUser(user), ID, id, VERSION, version.orElse(ALL), PAGE, page);
return handleSearchResource(ValueSet.class, OWNER, formatUser(user), ID, id, VERSION, version.orElse(ALL));
}

Expand Down Expand Up @@ -359,9 +387,9 @@ private Parameters valueSetVCParameters(String url, String valueSetId, String va
parameters.addParameter().setName(URL).setValue(new UriType(url));
if (isValid(valueSetId))
parameters.addParameter().setName("valueSetId").setValue(newStringType(valueSetId));
if (isValid(valueSetVersion))
parameters.addParameter().setName(SYSTEM_VERSION).setValue(newStringType(systemVersion));
if (isValid(systemVersion))
parameters.addParameter().setName(SYSTEM_VERSION).setValue(newStringType(systemVersion));
if (isValid(valueSetVersion))
parameters.addParameter().setName(VALUESET_VERSION).setValue(newStringType(valueSetVersion));
if (isValid(display))
parameters.addParameter().setName(DISPLAY).setValue(newStringType(display));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package org.openconceptlab.fhir.converter;

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.gson.*;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.r4.model.*;
Expand All @@ -25,6 +22,7 @@
import org.openconceptlab.fhir.repository.SourceRepository;
import org.openconceptlab.fhir.util.OclFhirUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Component;

/**
Expand Down Expand Up @@ -52,14 +50,14 @@ public CodeSystemConverter(SourceRepository sourceRepository, ConceptRepository
this.conceptsSourceRepository = conceptsSourceRepository;
}

public List<CodeSystem> convertToCodeSystem(List<Source> sources, boolean includeConcepts) {
public List<CodeSystem> convertToCodeSystem(List<Source> sources, boolean includeConcepts, int page) {
List<CodeSystem> codeSystems = new ArrayList<>();
sources.forEach(source -> {
// convert to base
CodeSystem codeSystem = toBaseCodeSystem(source);
if (includeConcepts) {
// add concepts
addConceptsToCodeSystem(codeSystem, source);
addConceptsToCodeSystem(codeSystem, source, page);
}
codeSystems.add(codeSystem);
});
Expand Down Expand Up @@ -96,7 +94,7 @@ private CodeSystem toBaseCodeSystem(final Source source){
codeSystem.setDescription(source.getDescription());
}
// count
codeSystem.setCount((int) getConceptsCount(source));
codeSystem.setCount(conceptRepository.findConceptCountInSource(source.getId()));
// property
addProperty(codeSystem);
return codeSystem;
Expand Down Expand Up @@ -131,19 +129,9 @@ private long getConceptsCount(final Source source) {
return source.getConceptsSources().parallelStream().map(m -> m.getConcept().getMnemonic()).distinct().count();
}

private void addConceptsToCodeSystem(final CodeSystem codeSystem, final Source source) {
// ConceptsSource includes all concept versions, we need to include only most recent concept version
List<Concept> filtered = new ArrayList<>();
Multimap<String, Concept> mnemonicToConceptMap = HashMultimap.create();
source.getConceptsSources()
.stream()
.map(ConceptsSource::getConcept)
.forEach(c -> mnemonicToConceptMap.put(c.getMnemonic(), c));
mnemonicToConceptMap.asMap().forEach((mnemonic, concepts) -> {
concepts.stream().max(Comparator.comparing(Concept::getId)).ifPresent(filtered::add);
});

for (Concept concept : filtered) {
private void addConceptsToCodeSystem(final CodeSystem codeSystem, final Source source, int page) {
List<Concept> concepts = conceptRepository.findConcepts(source.getId(), PageRequest.of(page, 100));
for (Concept concept : concepts) {
CodeSystem.ConceptDefinitionComponent definitionComponent = new CodeSystem.ConceptDefinitionComponent();
// code
definitionComponent.setCode(concept.getMnemonic());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public void setInternalReferenceId(String internalReferenceId) {
}

public Boolean getIsActive() {
return this.isActive;
return this.isActive != null && this.isActive;
}

public void setIsActive(Boolean isActive) {
Expand Down Expand Up @@ -328,7 +328,7 @@ public void setPublicAccess(String publicAccess) {
}

public Boolean getReleased() {
return this.released;
return this.released !=null && this.released;
}

public void setReleased(Boolean released) {
Expand All @@ -344,7 +344,7 @@ public void setRepositoryType(String repositoryType) {
}

public Boolean getRetired() {
return this.retired;
return this.retired != null && this.retired;
}

public void setRetired(Boolean retired) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ public class Concept extends BaseOclEntity implements Serializable {
private UserProfile updatedBy;

// @LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy="concept", cascade = CascadeType.ALL)
@OneToMany(mappedBy="concept", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<ConceptsDescription> conceptsDescriptions;

// @LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy="concept", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@OneToMany(mappedBy="concept", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<ConceptsName> conceptsNames;

public Concept() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public void setInternalReferenceId(String internalReferenceId) {
}

public Boolean getIsActive() {
return this.isActive;
return this.isActive != null && this.isActive;
}

public void setIsActive(Boolean isActive) {
Expand Down Expand Up @@ -303,7 +303,7 @@ public void setReleased(Boolean released) {
}

public Boolean getRetired() {
return this.retired;
return this.retired != null && this.retired;
}

public void setRetired(Boolean retired) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.*;
import org.openconceptlab.fhir.converter.CodeSystemConverter;
Expand Down Expand Up @@ -52,7 +53,7 @@ public Class<? extends IBaseResource> getResourceType() {
@Transactional
public Bundle searchCodeSystems(RequestDetails details) {
List<Source> sources = filterHead(getSources(publicAccess));
List<CodeSystem> codeSystems = codeSystemConverter.convertToCodeSystem(sources, false);
List<CodeSystem> codeSystems = codeSystemConverter.convertToCodeSystem(sources, false, 0);
return OclFhirUtil.getBundle(codeSystems, details.getFhirServerBase(), details.getRequestPath());
}

Expand All @@ -66,10 +67,12 @@ public Bundle searchCodeSystems(RequestDetails details) {
@Transactional
public Bundle searchCodeSystemByUrl(@RequiredParam(name = CodeSystem.SP_URL) StringType url,
@OptionalParam(name = VERSION) StringType version,
@OptionalParam(name = PAGE) StringType page,
RequestDetails details) {
List<Source> sources = filterHead(getSourceByUrl(url, version, publicAccess));
boolean includeConcepts = !isValid(version) || !isVersionAll(version);
List<CodeSystem> codeSystems = codeSystemConverter.convertToCodeSystem(sources, includeConcepts);
List<CodeSystem> codeSystems = codeSystemConverter.convertToCodeSystem(sources, includeConcepts,
getPage(page));
return OclFhirUtil.getBundle(codeSystems, details.getFhirServerBase(), details.getRequestPath());
}

Expand All @@ -83,7 +86,7 @@ public Bundle searchCodeSystemByUrl(@RequiredParam(name = CodeSystem.SP_URL) Str
public Bundle searchCodeSystemByOwner(@RequiredParam(name = OWNER) StringType owner,
RequestDetails details) {
List<Source> sources = filterHead(getSourceByOwner(owner, publicAccess));
List<CodeSystem> codeSystems = codeSystemConverter.convertToCodeSystem(sources, false);
List<CodeSystem> codeSystems = codeSystemConverter.convertToCodeSystem(sources, false, 0);
return OclFhirUtil.getBundle(codeSystems, details.getFhirServerBase(), details.getRequestPath());
}

Expand All @@ -100,10 +103,11 @@ public Bundle searchCodeSystemByOwner(@RequiredParam(name = OWNER) StringType ow
public Bundle searchCodeSystemByOwnerAndId(@RequiredParam(name = OWNER) StringType owner,
@RequiredParam(name = ID) StringType id,
@OptionalParam(name = VERSION) StringType version,
@OptionalParam(name = PAGE) StringType page,
RequestDetails details) {
List<Source> sources = filterHead(getSourceByOwnerAndIdAndVersion(id, owner, version, publicAccess));
boolean includeConcepts = !isVersionAll(version);
List<CodeSystem> codeSystems = codeSystemConverter.convertToCodeSystem(sources, includeConcepts);
List<CodeSystem> codeSystems = codeSystemConverter.convertToCodeSystem(sources, includeConcepts, getPage(page));
return OclFhirUtil.getBundle(codeSystems, details.getFhirServerBase(), details.getRequestPath());
}

Expand Down Expand Up @@ -143,8 +147,8 @@ public Bundle searchCodeSystemByOwnerAndId(@RequiredParam(name = OWNER) StringTy
*/
@Operation(name = LOOKUP, idempotent = true)
@Transactional
public Parameters codeSystemLookUp(@OperationParam(name = CODE, type = CodeType.class) CodeType code,
@OperationParam(name = SYSTEM, type = UriType.class) UriType system,
public Parameters codeSystemLookUp(@OperationParam(name = CODE, type = CodeType.class, min = 1) CodeType code,
@OperationParam(name = SYSTEM, type = UriType.class, min = 1) UriType system,
@OperationParam(name = VERSION, type = StringType.class) StringType version,
@OperationParam(name = DISP_LANG, type = CodeType.class) CodeType displayLanguage,
@OperationParam(name = OWNER, type = StringType.class) StringType owner) {
Expand All @@ -157,8 +161,8 @@ public Parameters codeSystemLookUp(@OperationParam(name = CODE, type = CodeType.

@Operation(name = VALIDATE_CODE, idempotent = true)
@Transactional
public Parameters codeSystemValidateCode(@OperationParam(name = URL, type = UriType.class) UriType url,
@OperationParam(name = CODE, type = CodeType.class) CodeType code,
public Parameters codeSystemValidateCode(@OperationParam(name = URL, type = UriType.class, min = 1) UriType url,
@OperationParam(name = CODE, type = CodeType.class, min = 1) CodeType code,
@OperationParam(name = VERSION, type = StringType.class) StringType version,
@OperationParam(name = DISPLAY, type = StringType.class) StringType display,
@OperationParam(name = DISP_LANG, type = CodeType.class) CodeType displayLanguage,
Expand Down

0 comments on commit de831ae

Please sign in to comment.