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;
}
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);
}
}
}
}
}
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();
}
}
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.");
}
}
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.");
}
}
Aggregations