Search in sources :

Example 1 with BackupDescriptor

use of org.exist.backup.BackupDescriptor in project exist by eXist-db.

the class AppRestoreUtils method getAppsFromBackup.

/**
 * Inspect all collections which may belong to apps in the backup descriptor. Return a list
 * of {@link AppDetail} objects containing the symbolic path, name and version of every app
 * found.
 *
 * The method attempts to be fail safe to make sure even bad backups can be restored. Errors
 * reading package descriptors are thus only logged and should not abort the process.
 *
 * @param broker the broker to use for parsing the descriptor and obtaining the app root
 * @param descriptors a queue of backup descriptors to inspect
 * @return list of application details
 */
private static List<AppDetail> getAppsFromBackup(final DBBroker broker, final Deque<BackupDescriptor> descriptors) {
    final String appRoot = getAppRoot(broker);
    final List<AppDetail> result = new ArrayList<>();
    final XMLReaderPool parserPool = broker.getBrokerPool().getParserPool();
    for (final BackupDescriptor descriptor : descriptors) {
        final BackupDescriptor apps = descriptor.getChildBackupDescriptor(appRoot);
        if (apps != null) {
            getAppsFromSubColl(result, parserPool, apps);
        }
        final BackupDescriptor system = descriptor.getChildBackupDescriptor("system");
        if (system != null) {
            final BackupDescriptor repo = system.getChildBackupDescriptor("repo");
            if (repo != null) {
                getAppsFromSubColl(result, parserPool, repo);
            }
        }
    }
    return result;
}
Also used : XMLReaderPool(org.exist.util.XMLReaderPool) BackupDescriptor(org.exist.backup.BackupDescriptor)

Example 2 with BackupDescriptor

use of org.exist.backup.BackupDescriptor in project exist by eXist-db.

the class AppRestoreUtils method getAppsFromSubColl.

private static void getAppsFromSubColl(final List<AppDetail> result, final XMLReaderPool parserPool, final BackupDescriptor descriptor) {
    final List<String> collections = getSubcollectionNames(parserPool, descriptor);
    for (final String collection : collections) {
        final BackupDescriptor app = descriptor.getChildBackupDescriptor(collection);
        final InputSource is = app.getInputSource("expath-pkg.xml");
        if (is != null) {
            XMLReader reader = null;
            try {
                reader = parserPool.borrowXMLReader();
                reader.setContentHandler(new DefaultHandler() {

                    @Override
                    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                        if (PKG_NAMESPACE.equals(uri) && "package".equals(localName)) {
                            final String version = attributes.getValue("version");
                            final String name = attributes.getValue("name");
                            if (StringUtils.isEmpty(version) || StringUtils.isEmpty(name)) {
                                LOG.warn("Invalid package descriptor for {}", app.getSymbolicPath());
                                return;
                            }
                            try {
                                final AppDetail detail = new AppDetail(app.getSymbolicPath(), name, Semver.parse(version));
                                result.add(detail);
                            } catch (PackageException e) {
                                LOG.warn("Invalid semver found while parsing {}", app.getSymbolicPath());
                            }
                        }
                    }
                });
                reader.parse(is);
            } catch (IOException | SAXException e) {
                LOG.warn("Parse exception while parsing {}", app.getSymbolicPath("expath-pkg.xml", false));
            } finally {
                if (reader != null) {
                    parserPool.returnXMLReader(reader);
                }
            }
        }
    }
}
Also used : InputSource(org.xml.sax.InputSource) Attributes(org.xml.sax.Attributes) IOException(java.io.IOException) BackupDescriptor(org.exist.backup.BackupDescriptor) DefaultHandler(org.xml.sax.helpers.DefaultHandler) SAXException(org.xml.sax.SAXException) PackageException(org.expath.pkg.repo.PackageException) XMLReader(org.xml.sax.XMLReader)

Example 3 with BackupDescriptor

use of org.exist.backup.BackupDescriptor in project exist by eXist-db.

the class ListBackups method eval.

public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
    if (!context.getEffectiveUser().hasDbaRole()) {
        throw new XPathException("You must be a DBA to list available backups");
    }
    final String exportDir = args[0].getStringValue();
    Path dir = Paths.get(exportDir);
    if (!dir.isAbsolute()) {
        dir = ((Path) context.getBroker().getConfiguration().getProperty(BrokerPool.PROPERTY_DATA_DIR)).resolve(exportDir);
    }
    context.pushDocumentContext();
    try {
        final MemTreeBuilder builder = context.getDocumentBuilder();
        final int nodeNr = builder.startElement(DIRECTORY_ELEMENT, null);
        if (Files.isDirectory(dir) && Files.isReadable(dir)) {
            final Pattern pattern = Pattern.compile(BackupDirectory.FILE_REGEX);
            final Matcher matcher = pattern.matcher("");
            final List<Path> files = FileUtils.list(dir);
            for (final Path file : files) {
                matcher.reset(FileUtils.fileName(file));
                if (matcher.matches()) {
                    final BackupDescriptor descriptor;
                    try {
                        if (FileUtils.fileName(file).endsWith(".zip")) {
                            descriptor = new ZipArchiveBackupDescriptor(file);
                        } else {
                            final Path descriptorFile = file.resolve("db").resolve(BackupDescriptor.COLLECTION_DESCRIPTOR);
                            descriptor = new FileSystemBackupDescriptor(file, descriptorFile);
                        }
                        final Properties properties = descriptor.getProperties();
                        if (properties != null) {
                            final AttributesImpl attrs = new AttributesImpl();
                            attrs.addAttribute("", "file", "file", "CDATA", FileUtils.fileName(file));
                            builder.startElement(BACKUP_ELEMENT, attrs);
                            for (final Object o : properties.keySet()) {
                                final String key = o.toString();
                                builder.startElement(new QName(key, Namespaces.EXIST_NS, ""), null);
                                builder.characters((String) properties.get(key));
                                builder.endElement();
                            }
                            builder.endElement();
                        }
                    } catch (final IOException e) {
                    }
                }
            }
        }
        builder.endElement();
        return (builder.getDocument().getNode(nodeNr));
    } catch (final IOException ioe) {
        throw new XPathException(this, ioe);
    } finally {
        context.popDocumentContext();
    }
}
Also used : Path(java.nio.file.Path) Pattern(java.util.regex.Pattern) ZipArchiveBackupDescriptor(org.exist.backup.ZipArchiveBackupDescriptor) Matcher(java.util.regex.Matcher) QName(org.exist.dom.QName) IOException(java.io.IOException) Properties(java.util.Properties) FileSystemBackupDescriptor(org.exist.backup.FileSystemBackupDescriptor) ZipArchiveBackupDescriptor(org.exist.backup.ZipArchiveBackupDescriptor) BackupDescriptor(org.exist.backup.BackupDescriptor) AttributesImpl(org.xml.sax.helpers.AttributesImpl) MemTreeBuilder(org.exist.dom.memtree.MemTreeBuilder) FileSystemBackupDescriptor(org.exist.backup.FileSystemBackupDescriptor)

Example 4 with BackupDescriptor

use of org.exist.backup.BackupDescriptor in project exist by eXist-db.

the class RestoreHandler method restoreSubCollectionEntry.

private void restoreSubCollectionEntry(final Attributes atts) throws SAXException {
    final String name;
    if (atts.getValue("filename") != null) {
        name = atts.getValue("filename");
    } else {
        name = atts.getValue("name");
    }
    // exclude the /db/system, /db/system/security, /db/system/security/exist/groups collections and their sub-collections, as these have already been restored
    if ((XmldbURI.DB.equals(currentCollectionUri) && "system".equals(name)) || (XmldbURI.SYSTEM.equals(currentCollectionUri) && "security".equals(name)) || (XmldbURI.SYSTEM.append("security").append(RealmImpl.ID).equals(currentCollectionUri) && "groups".equals(name))) {
        return;
    }
    // parse the sub-collection descriptor and restore
    final BackupDescriptor subDescriptor = descriptor.getChildBackupDescriptor(name);
    if (subDescriptor != null) {
        if (pathsToIgnore.contains(subDescriptor.getSymbolicPath())) {
            listener.skipResources("Skipping app path " + subDescriptor.getSymbolicPath() + ". Newer version " + "is already installed.", subDescriptor.getNumberOfFiles());
            return;
        }
        final XMLReaderPool parserPool = broker.getBrokerPool().getParserPool();
        XMLReader reader = null;
        try {
            reader = parserPool.borrowXMLReader();
            final EXistInputSource is = subDescriptor.getInputSource();
            is.setEncoding(UTF_8.displayName());
            final RestoreHandler handler = new RestoreHandler(broker, transaction, subDescriptor, listener, pathsToIgnore);
            reader.setContentHandler(handler);
            reader.parse(is);
        } catch (final SAXParseException se) {
            listener.error("SAX exception while reading sub-collection " + subDescriptor.getSymbolicPath() + " for processing: " + se.getMessage());
        } catch (final IOException ioe) {
            listener.error("Could not read sub-collection for processing: " + ioe.getMessage());
        } finally {
            if (reader != null) {
                parserPool.returnXMLReader(reader);
            }
        }
    } else {
        listener.error("Collection " + descriptor.getSymbolicPath(name, false) + " does not exist or is not readable.");
    }
}
Also used : SAXParseException(org.xml.sax.SAXParseException) IOException(java.io.IOException) BackupDescriptor(org.exist.backup.BackupDescriptor) XMLReader(org.xml.sax.XMLReader)

Example 5 with BackupDescriptor

use of org.exist.backup.BackupDescriptor in project exist by eXist-db.

the class SystemImportHandler method restoreSubCollectionEntry.

private void restoreSubCollectionEntry(final Attributes atts) throws SAXException {
    final String name;
    if (atts.getValue("filename") != null) {
        name = atts.getValue("filename");
    } else {
        name = atts.getValue("name");
    }
    // exclude /db/system collection and sub-collections, as these have already been restored
    // if ((currentCollection.getURI().startsWith(XmldbURI.SYSTEM)))
    // return;
    // parse the sub-collection descriptor and restore
    final BackupDescriptor subDescriptor = descriptor.getChildBackupDescriptor(name);
    if (subDescriptor != null) {
        final XMLReaderPool parserPool = broker.getBrokerPool().getParserPool();
        XMLReader reader = null;
        try {
            reader = parserPool.borrowXMLReader();
            final EXistInputSource is = subDescriptor.getInputSource();
            is.setEncoding(UTF_8.displayName());
            final SystemImportHandler handler = new SystemImportHandler(broker, transaction, subDescriptor, listener);
            reader.setContentHandler(handler);
            reader.parse(is);
        } catch (final SAXParseException e) {
            throw new SAXException("Could not process collection: " + descriptor.getSymbolicPath(name, false), e);
        } catch (final IOException ioe) {
            throw new SAXException("Could not read sub-collection for processing: " + ioe.getMessage(), ioe);
        } finally {
            if (reader != null) {
                parserPool.returnXMLReader(reader);
            }
        }
    } else {
        listener.error("Collection " + descriptor.getSymbolicPath(name, false) + " does not exist or is not readable.");
    }
}
Also used : SAXParseException(org.xml.sax.SAXParseException) IOException(java.io.IOException) BackupDescriptor(org.exist.backup.BackupDescriptor) XMLReader(org.xml.sax.XMLReader) SAXException(org.xml.sax.SAXException)

Aggregations

BackupDescriptor (org.exist.backup.BackupDescriptor)5 IOException (java.io.IOException)4 XMLReader (org.xml.sax.XMLReader)3 SAXException (org.xml.sax.SAXException)2 SAXParseException (org.xml.sax.SAXParseException)2 Path (java.nio.file.Path)1 Properties (java.util.Properties)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 FileSystemBackupDescriptor (org.exist.backup.FileSystemBackupDescriptor)1 ZipArchiveBackupDescriptor (org.exist.backup.ZipArchiveBackupDescriptor)1 QName (org.exist.dom.QName)1 MemTreeBuilder (org.exist.dom.memtree.MemTreeBuilder)1 XMLReaderPool (org.exist.util.XMLReaderPool)1 PackageException (org.expath.pkg.repo.PackageException)1 Attributes (org.xml.sax.Attributes)1 InputSource (org.xml.sax.InputSource)1 AttributesImpl (org.xml.sax.helpers.AttributesImpl)1 DefaultHandler (org.xml.sax.helpers.DefaultHandler)1