Search in sources :

Example 1 with BatchUserInteraction

use of org.expath.pkg.repo.tui.BatchUserInteraction in project exist by eXist-db.

the class Deployment method installAndDeploy.

/**
 * Install and deploy a give xar archive. Dependencies are installed from
 * the PackageLoader.
 *
 * @param broker the broker to use
 * @param transaction the transaction for this deployment task
 * @param xar the .xar file to install
 * @param loader package loader to use
 * @param enforceDeps when set to true, the method will throw an exception if a dependency could not be resolved
 *                    or an older version of the required dependency is installed and needs to be replaced.
 * @return the collection path to which the package was deployed or Optional.empty if not deployed
 * @throws PackageException if package installation failed
 * @throws IOException in case of an IO error
 */
public Optional<String> installAndDeploy(final DBBroker broker, final Txn transaction, final XarSource xar, final PackageLoader loader, boolean enforceDeps) throws PackageException, IOException {
    final Optional<DocumentImpl> descriptor = getDescriptor(broker, xar);
    if (!descriptor.isPresent()) {
        throw new PackageException("Missing descriptor from package: " + xar.getURI());
    }
    final DocumentImpl document = descriptor.get();
    final ElementImpl root = (ElementImpl) document.getDocumentElement();
    final String name = root.getAttribute("name");
    final String pkgVersion = root.getAttribute("version");
    final Optional<ExistRepository> repo = broker.getBrokerPool().getExpathRepo();
    if (repo.isPresent()) {
        final Packages packages = repo.get().getParentRepo().getPackages(name);
        if (packages != null && (!enforceDeps || pkgVersion.equals(packages.latest().getVersion()))) {
            LOG.info("Application package {} already installed. Skipping.", name);
            final Package pkg = packages.latest();
            return Optional.of(getTargetCollection(broker, pkg, getPackageDir(pkg)));
        }
        InMemoryNodeSet deps;
        try {
            deps = findElements(root, DEPENDENCY_ELEMENT);
            for (final SequenceIterator i = deps.iterate(); i.hasNext(); ) {
                final Element dependency = (Element) i.nextItem();
                final String pkgName = dependency.getAttribute("package");
                final String processor = dependency.getAttribute("processor");
                final String versionStr = dependency.getAttribute("version");
                final String semVer = dependency.getAttribute("semver");
                final String semVerMin = dependency.getAttribute("semver-min");
                final String semVerMax = dependency.getAttribute("semver-max");
                PackageLoader.Version version = null;
                if (semVer != null) {
                    version = new PackageLoader.Version(semVer, true);
                } else if (semVerMax != null || semVerMin != null) {
                    version = new PackageLoader.Version(semVerMin, semVerMax);
                } else if (pkgVersion != null) {
                    version = new PackageLoader.Version(versionStr, false);
                }
                if (processor != null && processor.equals(PROCESSOR_NAME) && version != null) {
                    checkProcessorVersion(version);
                } else if (pkgName != null) {
                    LOG.info("Package {} depends on {}", name, pkgName);
                    boolean isInstalled = false;
                    if (repo.get().getParentRepo().getPackages(pkgName) != null) {
                        LOG.debug("Package {} already installed", pkgName);
                        Packages pkgs = repo.get().getParentRepo().getPackages(pkgName);
                        // check if installed package matches required version
                        if (pkgs != null) {
                            if (version != null) {
                                Package latest = pkgs.latest();
                                DependencyVersion depVersion = version.getDependencyVersion();
                                if (depVersion.isCompatible(latest.getVersion())) {
                                    isInstalled = true;
                                } else {
                                    LOG.debug("Package {} needs to be upgraded", pkgName);
                                    if (enforceDeps) {
                                        throw new PackageException("Package requires version " + version.toString() + " of package " + pkgName + ". Installed version is " + latest.getVersion() + ". Please upgrade!");
                                    }
                                }
                            } else {
                                isInstalled = true;
                            }
                            if (isInstalled) {
                                LOG.debug("Package {} already installed", pkgName);
                            }
                        }
                    }
                    if (!isInstalled && loader != null) {
                        final XarSource depFile = loader.load(pkgName, version);
                        if (depFile != null) {
                            installAndDeploy(broker, transaction, depFile, loader);
                        } else {
                            if (enforceDeps) {
                                LOG.warn("Missing dependency: package {} could not be resolved. This error is not fatal, but the package may not work as expected", pkgName);
                            } else {
                                throw new PackageException("Missing dependency: package " + pkgName + " could not be resolved.");
                            }
                        }
                    }
                }
            }
        } catch (final XPathException e) {
            throw new PackageException("Invalid descriptor found in " + xar.getURI());
        }
        // installing the xar into the expath repo
        LOG.info("Installing package {}", xar.getURI());
        final UserInteractionStrategy interact = new BatchUserInteraction();
        final org.expath.pkg.repo.Package pkg = repo.get().getParentRepo().installPackage(xar, true, interact);
        final ExistPkgInfo info = (ExistPkgInfo) pkg.getInfo("exist");
        if (info != null && !info.getJars().isEmpty()) {
            ClasspathHelper.updateClasspath(broker.getBrokerPool(), pkg);
        }
        broker.getBrokerPool().getXQueryPool().clear();
        final String pkgName = pkg.getName();
        // signal status
        broker.getBrokerPool().reportStatus("Installing app: " + pkg.getAbbrev());
        repo.get().reportAction(ExistRepository.Action.INSTALL, pkg.getName());
        LOG.info("Deploying package {}", pkgName);
        return deploy(broker, transaction, pkgName, repo, null);
    }
    // Totally unnecessary to do the above if repo is unavailable.
    return Optional.empty();
}
Also used : Element(org.w3c.dom.Element) org.expath.pkg.repo(org.expath.pkg.repo) SequenceIterator(org.exist.xquery.value.SequenceIterator) DependencyVersion(org.expath.pkg.repo.deps.DependencyVersion) DependencyVersion(org.expath.pkg.repo.deps.DependencyVersion) Package(org.expath.pkg.repo.Package) Package(org.expath.pkg.repo.Package) BatchUserInteraction(org.expath.pkg.repo.tui.BatchUserInteraction)

Example 2 with BatchUserInteraction

use of org.expath.pkg.repo.tui.BatchUserInteraction in project exist by eXist-db.

the class RemoveFunction method eval.

public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    Sequence removed = BooleanValue.TRUE;
    boolean force = false;
    UserInteractionStrategy interact = new BatchUserInteraction();
    String pkg = args[0].getStringValue();
    try {
        Optional<ExistRepository> repo = getContext().getRepository();
        if (repo.isPresent()) {
            Repository parent_repo = repo.get().getParentRepo();
            parent_repo.removePackage(pkg, force, interact);
            repo.get().reportAction(ExistRepository.Action.UNINSTALL, pkg);
            context.getBroker().getBrokerPool().getXQueryPool().clear();
        } else {
            throw new XPathException("expath repository not available");
        }
    } catch (PackageException | XPathException pe) {
        return BooleanValue.FALSE;
    // /TODO: _repo.removePackage seems to throw PackageException
    // throw new XPathException("Problem removing package " + pkg + " in expath repository, check that eXist-db has access permissions to expath repository file directory  ", pe);
    }
    return removed;
}
Also used : Repository(org.expath.pkg.repo.Repository) ExistRepository(org.exist.repo.ExistRepository) UserInteractionStrategy(org.expath.pkg.repo.UserInteractionStrategy) XPathException(org.exist.xquery.XPathException) PackageException(org.expath.pkg.repo.PackageException) BatchUserInteraction(org.expath.pkg.repo.tui.BatchUserInteraction) ExistRepository(org.exist.repo.ExistRepository)

Example 3 with BatchUserInteraction

use of org.expath.pkg.repo.tui.BatchUserInteraction in project exist by eXist-db.

the class RestoreAppsTest method removePackage.

private void removePackage(BrokerPool pool) throws PackageException {
    Optional<ExistRepository> repo = pool.getExpathRepo();
    Repository parent_repo = repo.get().getParentRepo();
    parent_repo.removePackage("http://existsolutions.com/apps/backup-test", true, new BatchUserInteraction());
}
Also used : ExistRepository(org.exist.repo.ExistRepository) BatchUserInteraction(org.expath.pkg.repo.tui.BatchUserInteraction) ExistRepository(org.exist.repo.ExistRepository)

Example 4 with BatchUserInteraction

use of org.expath.pkg.repo.tui.BatchUserInteraction in project exist by eXist-db.

the class InstallFunction method eval.

public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    Sequence removed = BooleanValue.FALSE;
    boolean force = true;
    UserInteractionStrategy interact = new BatchUserInteraction();
    String pkgOrPath = args[0].getStringValue();
    Optional<ExistRepository> repo = getContext().getRepository();
    try {
        if (repo.isPresent()) {
            Repository parent_repo = repo.get().getParentRepo();
            Package pkg;
            if (isCalledAs("install")) {
                // download .xar from a URI
                URI uri = _getURI(pkgOrPath);
                pkg = parent_repo.installPackage(uri, force, interact);
                repo.get().reportAction(ExistRepository.Action.INSTALL, pkg.getName());
            } else {
                // .xar is stored as a binary resource
                try (final LockedDocument lockedDoc = getBinaryDoc(pkgOrPath);
                    final Txn transaction = context.getBroker().continueOrBeginTransaction()) {
                    final DocumentImpl doc = lockedDoc.getDocument();
                    LOG.debug("Installing file: {}", doc.getURI());
                    pkg = parent_repo.installPackage(new BinaryDocumentXarSource(context.getBroker().getBrokerPool(), transaction, (BinaryDocument) doc), force, interact);
                    repo.get().reportAction(ExistRepository.Action.INSTALL, pkg.getName());
                    transaction.commit();
                }
            }
            ExistPkgInfo info = (ExistPkgInfo) pkg.getInfo("exist");
            if (info != null && !info.getJars().isEmpty())
                ClasspathHelper.updateClasspath(context.getBroker().getBrokerPool(), pkg);
            // TODO: expath libs do not provide a way to see if there were any XQuery modules installed at all
            context.getBroker().getBrokerPool().getXQueryPool().clear();
            removed = BooleanValue.TRUE;
        } else {
            throw new XPathException("expath repository not available");
        }
    } catch (PackageException | TransactionException ex) {
        logger.error(ex.getMessage(), ex);
        return removed;
    // /TODO: _repo.removePackage seems to throw PackageException
    // throw new XPathException("Problem installing package " + pkg + " in expath repository, check that eXist-db has access permissions to expath repository file directory  ", ex);
    } catch (XPathException xpe) {
        logger.error(xpe.getMessage());
        return removed;
    }
    return removed;
}
Also used : XPathException(org.exist.xquery.XPathException) Sequence(org.exist.xquery.value.Sequence) Txn(org.exist.storage.txn.Txn) XmldbURI(org.exist.xmldb.XmldbURI) URI(java.net.URI) DocumentImpl(org.exist.dom.persistent.DocumentImpl) ExistPkgInfo(org.exist.repo.ExistPkgInfo) ExistRepository(org.exist.repo.ExistRepository) TransactionException(org.exist.storage.txn.TransactionException) LockedDocument(org.exist.dom.persistent.LockedDocument) Package(org.expath.pkg.repo.Package) BatchUserInteraction(org.expath.pkg.repo.tui.BatchUserInteraction) ExistRepository(org.exist.repo.ExistRepository)

Aggregations

BatchUserInteraction (org.expath.pkg.repo.tui.BatchUserInteraction)4 ExistRepository (org.exist.repo.ExistRepository)3 XPathException (org.exist.xquery.XPathException)2 Package (org.expath.pkg.repo.Package)2 URI (java.net.URI)1 DocumentImpl (org.exist.dom.persistent.DocumentImpl)1 LockedDocument (org.exist.dom.persistent.LockedDocument)1 ExistPkgInfo (org.exist.repo.ExistPkgInfo)1 TransactionException (org.exist.storage.txn.TransactionException)1 Txn (org.exist.storage.txn.Txn)1 XmldbURI (org.exist.xmldb.XmldbURI)1 Sequence (org.exist.xquery.value.Sequence)1 SequenceIterator (org.exist.xquery.value.SequenceIterator)1 org.expath.pkg.repo (org.expath.pkg.repo)1 PackageException (org.expath.pkg.repo.PackageException)1 Repository (org.expath.pkg.repo.Repository)1 UserInteractionStrategy (org.expath.pkg.repo.UserInteractionStrategy)1 DependencyVersion (org.expath.pkg.repo.deps.DependencyVersion)1 Element (org.w3c.dom.Element)1