Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

install-package-by-b64 #2167

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
implemented-feature
  • Loading branch information
9x00001 authored and 9x00001 committed Nov 10, 2020
commit fe8ecc86c20170eff46997bfed9882ec03730f0b
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
* #L%
*/

import org.hl7.fhir.r4.model.Base64BinaryType;

public interface IPackageInstallerSvc {

PackageInstallOutcomeJson install(PackageInstallationSpec theSpec);

PackageInstallOutcomeJson installByPackage(Base64BinaryType packageFile);
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Base64BinaryType;
import org.hl7.fhir.r4.model.Identifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -59,6 +60,7 @@
import org.hl7.fhir.utilities.npm.NpmPackage;

import javax.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -148,20 +150,8 @@ public PackageInstallOutcomeJson install(PackageInstallationSpec theInstallation
if (enabled) {
try {

boolean exists = new TransactionTemplate(myTxManager).execute(tx -> {
Optional<NpmPackageVersionEntity> existing = myPackageVersionDao.findByPackageIdAndVersion(theInstallationSpec.getName(), theInstallationSpec.getVersion());
return existing.isPresent();
});
if (exists) {
ourLog.info("Package {}#{} is already installed", theInstallationSpec.getName(), theInstallationSpec.getVersion());
}

NpmPackage npmPackage = myPackageCacheManager.installPackage(theInstallationSpec);
if (npmPackage == null) {
throw new IOException("Package not found");
}

retVal.getMessage().addAll(JpaPackageCache.getProcessingMessages(npmPackage));
validateAndInstallPkg(npmPackage, theInstallationSpec, retVal);

if (theInstallationSpec.isFetchDependencies()) {
fetchAndInstallDependencies(npmPackage, theInstallationSpec, retVal);
Expand All @@ -182,6 +172,43 @@ public PackageInstallOutcomeJson install(PackageInstallationSpec theInstallation
return retVal;
}

/**
* Loads and installs an IG from a B64 String
* <p>
* Installs the IG by persisting instances of the following types of resources:
* <p>
* - NamingSystem, CodeSystem, ValueSet, StructureDefinition (with snapshots),
* ConceptMap, SearchParameter, Subscription
* <p>
* Creates the resources if non-existent, updates them otherwise.
*
* @param theInstallationSpec The details about what should be installed
*/
@Override
public PackageInstallOutcomeJson installByPackage(Base64BinaryType packageFile) {
PackageInstallOutcomeJson retVal = new PackageInstallOutcomeJson();
if (enabled) {
try {
byte[] decodedB64Package = packageFile.getValue();
ByteArrayInputStream packageStream = new ByteArrayInputStream(decodedB64Package);

NpmPackage npmPackage = NpmPackage.fromPackage(packageStream);
PackageInstallationSpec theInstallationSpec = new PackageInstallationSpec();
theInstallationSpec.setName(npmPackage.name());
theInstallationSpec.setVersion((npmPackage.version()));
theInstallationSpec.setFetchDependencies(false);
theInstallationSpec.setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL);

validateAndInstallPkg(npmPackage, theInstallationSpec, retVal);

} catch (IOException e) {
throw new ImplementationGuideInstallationException("Could not load NPM package ", e);
}
}

return retVal;
}

/**
* Installs a package and its dependencies.
* <p>
Expand Down Expand Up @@ -439,6 +466,25 @@ private boolean resourceHasUrlElement(IBaseResource resource) {
return nextDef != null;
}

private void validateAndInstallPkg(NpmPackage npmPackage, PackageInstallationSpec theInstallationSpec, PackageInstallOutcomeJson retVal) throws IOException {
boolean exists = new TransactionTemplate(myTxManager).execute(tx -> {
Optional<NpmPackageVersionEntity> existing = myPackageVersionDao.findByPackageIdAndVersion(theInstallationSpec.getName(), theInstallationSpec.getVersion());
return existing.isPresent();
});
if (exists) {
ourLog.info("Package {}#{} is already installed", theInstallationSpec.getName(), theInstallationSpec.getVersion());
throw new ImplementationGuideInstallationException("NPM package already installed");
}

install(npmPackage, theInstallationSpec, new PackageInstallOutcomeJson());

if (npmPackage == null) {
throw new IOException("Package not found");
}

retVal.getMessage().addAll(JpaPackageCache.getProcessingMessages(npmPackage));
}

@VisibleForTesting
void setFhirContextForUnitTest(FhirContext theCtx) {
myFhirContext = theCtx;
Expand Down