All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ca.uhn.hapi.fhir.docs.Copier Maven / Gradle / Ivy

/*-
 * #%L
 * HAPI FHIR - Docs
 * %%
 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package ca.uhn.hapi.fhir.docs;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.util.ResourceReferenceInfo;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.apache.commons.lang3.StringUtils.isNotBlank;

@SuppressWarnings("unused")
public class Copier {
	private static final Logger ourLog = LoggerFactory.getLogger(Copier.class);

	public static void main(String[] args) {
		FhirContext ctx = FhirContext.forDstu3();
		IGenericClient source = ctx.newRestfulGenericClient("http://localhost:8080/baseDstu3");
		IGenericClient target = ctx.newRestfulGenericClient("https://try.smilecdr.com:8000");

		List resType = Arrays.asList(
				"Patient",
				"Organization",
				"Encounter",
				"Procedure",
				"Observation",
				"ResearchSubject",
				"Specimen",
				"ResearchStudy",
				"Location",
				"Practitioner");

		List queued = new ArrayList<>();
		Set sent = new HashSet<>();
		for (String next : resType) {
			copy(ctx, source, target, next, queued, sent);
		}

		while (queued.size() > 0) {
			ourLog.info("Have {} queued resources to deliver", queued.size());

			for (IBaseResource nextQueued : new ArrayList<>(queued)) {

				String missingRef = null;
				for (ResourceReferenceInfo nextRefInfo : ctx.newTerser().getAllResourceReferences(nextQueued)) {
					String nextRef = nextRefInfo
							.getResourceReference()
							.getReferenceElement()
							.getValue();
					if (isNotBlank(nextRef) && !sent.contains(nextRef)) {
						missingRef = nextRef;
					}
				}
				if (missingRef != null) {
					ourLog.info(
							"Can't send {} because of missing ref {}",
							nextQueued.getIdElement().getIdPart(),
							missingRef);
					continue;
				}

				IIdType newId = target.update().resource(nextQueued).execute().getId();

				ourLog.info(
						"Copied resource {} and got ID {}",
						nextQueued.getIdElement().getValue(),
						newId);
				sent.add(nextQueued.getIdElement().toUnqualifiedVersionless().getValue());
				queued.remove(nextQueued);
			}
		}
	}

	private static void copy(
			FhirContext theCtx,
			IGenericClient theSource,
			IGenericClient theTarget,
			String theResType,
			List theQueued,
			Set theSent) {
		Bundle received = theSource
				.search()
				.forResource(theResType)
				.returnBundle(Bundle.class)
				.execute();
		copy(theCtx, theTarget, theResType, theQueued, theSent, received);

		while (received.getLink("next") != null) {
			ourLog.info("Fetching next page...");
			received = theSource.loadPage().next(received).execute();
			copy(theCtx, theTarget, theResType, theQueued, theSent, received);
		}
	}

	private static void copy(
			FhirContext theCtx,
			IGenericClient theTarget,
			String theResType,
			List theQueued,
			Set theSent,
			Bundle theReceived) {
		for (Bundle.BundleEntryComponent nextEntry : theReceived.getEntry()) {
			Resource nextResource = nextEntry.getResource();
			nextResource.setId(
					theResType + "/" + "CR-" + nextResource.getIdElement().getIdPart());

			boolean haveUnsentReference = false;
			for (ResourceReferenceInfo nextRefInfo : theCtx.newTerser().getAllResourceReferences(nextResource)) {
				IIdType nextRef = nextRefInfo.getResourceReference().getReferenceElement();
				if (nextRef.hasIdPart()) {
					String newRef = nextRef.getResourceType() + "/" + "CR-" + nextRef.getIdPart();
					ourLog.info("Changing reference {} to {}", nextRef.getValue(), newRef);
					nextRefInfo.getResourceReference().setReference(newRef);
					if (!theSent.contains(newRef)) {
						haveUnsentReference = true;
					}
				}
			}

			if (haveUnsentReference) {
				ourLog.info("Queueing {} for delivery after", nextResource.getId());
				theQueued.add(nextResource);
				continue;
			}

			IIdType newId = theTarget.update().resource(nextResource).execute().getId();

			ourLog.info("Copied resource {} and got ID {}", nextResource.getId(), newId);
			theSent.add(nextResource.getIdElement().toUnqualifiedVersionless().getValue());
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy