package uk.nhs.careconnect.ccri.fhirserver.stu3.provider; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.rest.annotation.*; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.ValidationModeEnum; import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.UriParam; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import org.apache.http.HttpHeaders; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClientBuilder; import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.IdType; import org.hl7.fhir.dstu3.model.OperationOutcome; import org.hl7.fhir.dstu3.model.StructureDefinition; import org.hl7.fhir.instance.model.api.IBaseResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import uk.nhs.careconnect.ccri.fhirserver.support.OperationOutcomeFactory; import uk.nhs.careconnect.ccri.fhirserver.support.ProviderResponseLibrary; import uk.nhs.careconnect.fhir.OperationOutcomeException; import uk.nhs.careconnect.ri.database.daointerface.StructureDefinitionRepository; import javax.servlet.http.HttpServletRequest; import java.io.InputStreamReader; import java.io.Reader; import java.net.UnknownHostException; import java.util.List; @Component public class StructureDefinitionProvider implements ICCResourceProvider { @Autowired private ResourcePermissionProvider resourcePermissionProvider; @Autowired private ResourceTestProvider resourceTestProvider; @Override public Class<StructureDefinition> getResourceType() { return StructureDefinition.class; } @Autowired private StructureDefinitionRepository structureDefinitionDao; @Autowired FhirContext ctx; private static final Logger log = LoggerFactory.getLogger(StructureDefinitionProvider.class); @Override public Long count() { return structureDefinitionDao.count(); } @Search public List<StructureDefinition> search(HttpServletRequest theRequest, @OptionalParam(name = StructureDefinition.SP_NAME) StringParam name, @OptionalParam(name = StructureDefinition.SP_PUBLISHER) StringParam publisher, @OptionalParam(name = StructureDefinition.SP_URL) UriParam url ) { return structureDefinitionDao.search(ctx, name, publisher, url); } @Read public StructureDefinition get (@IdParam IdType internalId) { resourcePermissionProvider.checkPermission("read"); StructureDefinition structureDefinition = structureDefinitionDao.read( ctx, internalId); if ( structureDefinition == null) { throw OperationOutcomeFactory.buildOperationOutcomeException( new ResourceNotFoundException("No StructureDefinition/" + internalId.getIdPart()), OperationOutcome.IssueType.NOTFOUND); } return structureDefinition; } @Create public MethodOutcome create(HttpServletRequest theRequest, @ResourceParam StructureDefinition structureDefinition) { log.info("create method is called"); resourcePermissionProvider.checkPermission("create"); MethodOutcome method = new MethodOutcome(); OperationOutcome opOutcome = new OperationOutcome(); method.setOperationOutcome(opOutcome); try { StructureDefinition newStructureDefinition = structureDefinitionDao.create(ctx,structureDefinition); method.setCreated(true); method.setId(newStructureDefinition.getIdElement()); method.setResource(newStructureDefinition); } catch (BaseServerResponseException srv) { // HAPI Exceptions pass through throw srv; } catch(Exception ex) { ProviderResponseLibrary.handleException(method,ex); } return method; } @Update() public MethodOutcome update(HttpServletRequest theRequest,@ResourceParam StructureDefinition structureDefinition) throws OperationOutcomeException { log.info("update method is called"); resourcePermissionProvider.checkPermission("update"); MethodOutcome method = new MethodOutcome(); try { StructureDefinition newStructureDefinition = structureDefinitionDao.create(ctx,structureDefinition); method.setCreated(false); method.setId(newStructureDefinition.getIdElement()); method.setResource(newStructureDefinition); } catch (BaseServerResponseException srv) { // HAPI Exceptions pass through throw srv; } catch(Exception ex) { ProviderResponseLibrary.handleException(method,ex); } return method; } @Delete public MethodOutcome delete (@IdParam IdType internalId) { resourcePermissionProvider.checkPermission("delete"); MethodOutcome method = new MethodOutcome(); try { OperationOutcome outcome = structureDefinitionDao.delete(ctx,internalId); method.setCreated(false); //method.setId(newStructureDefinition.getIdElement()); method.setResource(outcome); } catch (Exception ex) { log.info(ex.getMessage()); ProviderResponseLibrary.handleException(method,ex); } return method; } @Validate public MethodOutcome testResource(@ResourceParam StructureDefinition resource, @Validate.Mode ValidationModeEnum theMode, @Validate.Profile String theProfile) { return resourceTestProvider.testResource(resource,theMode,theProfile); } @Operation(name = "$refresh", idempotent = true, bundleType= BundleTypeEnum.COLLECTION) public MethodOutcome refresh( @OperationParam(name="id") TokenParam structureDefinitionId, @OperationParam(name="query") ReferenceParam structureDefinitionQuery ) throws Exception { HttpClient client1 = getHttpClient(); HttpGet request = null; if (structureDefinitionId != null) { request = new HttpGet(structureDefinitionQuery.getValue()); } if (structureDefinitionQuery != null) { request = new HttpGet(structureDefinitionQuery.getValue()); } request.setHeader(HttpHeaders.CONTENT_TYPE, "application/fhir+json"); request.setHeader(HttpHeaders.ACCEPT, "application/fhir+json"); Bundle bundle = getRequest(client1,request,structureDefinitionId); Boolean next = false; do { next = false; for (Bundle.BundleLinkComponent link : bundle.getLink()) { if (link.getRelation().equals("next")) { next = true; client1 = getHttpClient(); request = new HttpGet(link.getUrl()); request.setHeader(HttpHeaders.CONTENT_TYPE, "application/fhir+json"); request.setHeader(HttpHeaders.ACCEPT, "application/fhir+json"); } } if (next) { log.info("Get next bundle "+request.getURI()); bundle = getRequest(client1,request,structureDefinitionId); } log.info("Iteration check = "+ next.toString()); } while (next); log.info("Finished"); MethodOutcome retVal = new MethodOutcome(); return retVal; } private Bundle getRequest(HttpClient client1, HttpGet request, TokenParam structureDefinitionId) { Bundle bundle = null; HttpResponse response; Reader reader; try { //request.setEntity(new StringEntity(ctx.newJsonParser().encodeResourceToString(resourceToValidate))); response = client1.execute(request); reader = new InputStreamReader(response.getEntity().getContent()); IBaseResource resource = ctx.newJsonParser().parseResource(reader); //System.out.println(ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resource)); System.out.println("resource = " + resource); if(resource instanceof Bundle) { bundle = (Bundle) resource; System.out.println("Entry Count = " + bundle.getEntry().size()); System.out.println(ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); //retVal.setOperationOutcome(operationOutcome); for (Bundle.BundleEntryComponent entry : bundle.getEntry()) { System.out.println(" valueset id = " + entry.getResource().getId() ); if (entry.hasResource() && entry.getResource() instanceof StructureDefinition && (structureDefinitionId.getValue().contains("ALL") || structureDefinitionId.getValue().contains(entry.getResource().getId()) )) { StructureDefinition vs = (StructureDefinition) entry.getResource(); System.out.println("URL IS " + vs.getUrl()); HttpClient client2 = getHttpClient(); HttpGet request1 = new HttpGet(vs.getUrl()); request1.setHeader(HttpHeaders.CONTENT_TYPE, "application/fhir+json"); request1.setHeader(HttpHeaders.ACCEPT, "application/fhir+json"); try { HttpResponse response1 = client2.execute(request1); System.out.println(response1.getStatusLine()); if(response1.getStatusLine().toString().contains("200")) { //if (response.get .Content.Headers.ContentType.MediaType == "application/json") reader = new InputStreamReader(response1.getEntity().getContent()); resource = ctx.newJsonParser().parseResource(reader); System.out.println(ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resource)); if(resource instanceof StructureDefinition ) { StructureDefinition newVS = (StructureDefinition) resource; newVS.setName(newVS.getName()+ ".."); List<StructureDefinition> results = structureDefinitionDao.search(ctx,null,null,new UriParam().setValue(newVS.getUrl())); if (results.size()>0) { newVS.setId(results.get(0).getIdElement().getIdPart()); } StructureDefinition newStructureDefinition = structureDefinitionDao.create(ctx, newVS); System.out.println(ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(newStructureDefinition)); System.out.println("newStructureDefinition.getIdElement()" + newStructureDefinition.getIdElement()); // StructureDefinitionComposeComponent vscc = newVS.code .getCompose(); System.out.println("code concept" + newVS.getId()); } } } catch(UnknownHostException e) {System.out.println("Host not known");} } } } else { throw new InternalErrorException("Server Error", (OperationOutcome) resource); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return bundle; } private HttpClient getHttpClient(){ final HttpClient httpClient = HttpClientBuilder.create().build(); return httpClient; } }