Search in sources :

Example 1 with LockMode

use of org.exist.storage.lock.Lock.LockMode in project exist by eXist-db.

the class NativeBroker method getXMLResource.

@Override
public LockedDocument getXMLResource(XmldbURI fileName, final LockMode lockMode) throws PermissionDeniedException {
    if (fileName == null) {
        return null;
    }
    fileName = prepend(fileName.toCollectionPathURI());
    // TODO : resolve URIs !
    final XmldbURI collUri = fileName.removeLastSegment();
    final XmldbURI docUri = fileName.lastSegment();
    final LockMode collectionLockMode = lockManager.relativeCollectionLockMode(LockMode.READ_LOCK, lockMode);
    try (final Collection collection = openCollection(collUri, collectionLockMode)) {
        if (collection == null) {
            LOG.debug("Collection '{}' not found!", collUri);
            return null;
        }
        try {
            // if (!collection.getPermissions().validate(getCurrentSubject(), Permission.EXECUTE)) {
            // throw new PermissionDeniedException("Permission denied to read collection '" + collUri + "' by " + getCurrentSubject().getName());
            // }
            final LockedDocument lockedDocument = collection.getDocumentWithLock(this, docUri, lockMode);
            // NOTE: early release of Collection lock inline with Asymmetrical Locking scheme
            collection.close();
            if (lockedDocument == null) {
                // LOG.debug("document '" + fileName + "' not found!");
                return null;
            }
            // if (!doc.getMode().validate(getUser(), Permission.READ))
            // throw new PermissionDeniedException("not allowed to read document");
            final DocumentImpl doc = lockedDocument.getDocument();
            return lockedDocument;
        } catch (final LockException e) {
            LOG.error("Could not acquire lock on document {}", fileName, e);
        // TODO : exception ? -pb
        }
    }
    return null;
}
Also used : Collection(org.exist.collections.Collection) LockMode(org.exist.storage.lock.Lock.LockMode) XmldbURI(org.exist.xmldb.XmldbURI)

Example 2 with LockMode

use of org.exist.storage.lock.Lock.LockMode in project exist by eXist-db.

the class RpcConnection method beginProtected.

protected LockedDocumentMap beginProtected(final DBBroker broker, final Map<String, Object> parameters) throws EXistException, PermissionDeniedException {
    final String protectColl = (String) parameters.get(RpcAPI.PROTECTED_MODE);
    if (protectColl == null) {
        return null;
    }
    int retries = BEGIN_PROTECTED_MAX_LOCKING_RETRIES == -1 ? -1 : BEGIN_PROTECTED_MAX_LOCKING_RETRIES - 2;
    do {
        MutableDocumentSet docs = null;
        final LockedDocumentMap lockedDocuments = new LockedDocumentMap();
        final LockMode documentLockMode = LockMode.WRITE_LOCK;
        final LockMode collectionLockMode = broker.getBrokerPool().getLockManager().relativeCollectionLockMode(LockMode.READ_LOCK, documentLockMode);
        try (final Collection coll = broker.openCollection(XmldbURI.createInternal(protectColl), collectionLockMode)) {
            docs = new DefaultDocumentSet();
            coll.allDocs(broker, docs, true, lockedDocuments, documentLockMode);
            return lockedDocuments;
        } catch (final LockException e) {
            LOG.warn("Deadlock detected. Starting over again. Docs: {}; locked: {}. Cause: {}", docs.getDocumentCount(), lockedDocuments.size(), e.getMessage());
            lockedDocuments.unlock();
        }
        retries--;
    } while (retries >= -1);
    throw new EXistException("Unable to beginProtected after " + BEGIN_PROTECTED_MAX_LOCKING_RETRIES + " retries");
}
Also used : Collection(org.exist.collections.Collection) LockedDocumentMap(org.exist.storage.lock.LockedDocumentMap) LockMode(org.exist.storage.lock.Lock.LockMode) EXistException(org.exist.EXistException)

Example 3 with LockMode

use of org.exist.storage.lock.Lock.LockMode in project exist by eXist-db.

the class DocUtils method getDocumentByPathFromDB.

private static Sequence getDocumentByPathFromDB(final XQueryContext context, final String path) throws XPathException, PermissionDeniedException {
    // check if the loaded documents should remain locked
    final LockMode lockType = context.lockDocumentsOnLoad() ? LockMode.WRITE_LOCK : LockMode.READ_LOCK;
    try {
        final XmldbURI baseURI = context.getBaseURI().toXmldbURI();
        final XmldbURI pathUri;
        if (baseURI != null && !(baseURI.equals("") || baseURI.equals("/db"))) {
            // relative collection Path: add the current base URI
            pathUri = baseURI.resolveCollectionPath(XmldbURI.xmldbUriFor(path, false));
        } else {
            pathUri = XmldbURI.xmldbUriFor(path, false);
        }
        // relative collection Path: add the current module call URI if applicable
        final XmldbURI resourceUri = Optional.ofNullable(context.getModuleLoadPath()).filter(moduleLoadPath -> !moduleLoadPath.isEmpty()).flatMap(moduleLoadPath -> Try(() -> XmldbURI.xmldbUriFor(moduleLoadPath)).toOption()).map(moduleLoadPath -> moduleLoadPath.resolveCollectionPath(pathUri)).orElse(pathUri);
        // try to open the document and acquire a lock
        try (final LockedDocument lockedDoc = context.getBroker().getXMLResource(resourceUri, lockType)) {
            if (lockedDoc == null) {
                return Sequence.EMPTY_SEQUENCE;
            } else {
                final DocumentImpl doc = lockedDoc.getDocument();
                if (!doc.getPermissions().validate(context.getSubject(), Permission.READ)) {
                    throw new PermissionDeniedException("Insufficient privileges to read resource " + path);
                }
                if (doc.getResourceType() == DocumentImpl.BINARY_FILE) {
                    throw new XPathException("Document " + path + " is a binary resource, not an XML document. Please consider using the function util:binary-doc() to retrieve a reference to it.");
                }
                return new NodeProxy(doc);
            }
        }
    } catch (final URISyntaxException e) {
        throw new XPathException(e);
    }
}
Also used : LockMode(org.exist.storage.lock.Lock.LockMode) SAXNotSupportedException(org.xml.sax.SAXNotSupportedException) BrokerPool(org.exist.storage.BrokerPool) XMLReaderPool(org.exist.util.XMLReaderPool) ErrorCodes(org.exist.xquery.ErrorCodes) NodeProxy(org.exist.dom.persistent.NodeProxy) PermissionDeniedException(org.exist.security.PermissionDeniedException) SAXNotRecognizedException(org.xml.sax.SAXNotRecognizedException) XMLReader(org.xml.sax.XMLReader) Source(org.exist.source.Source) java.net(java.net) Namespaces(org.exist.Namespaces) Document(org.w3c.dom.Document) XmldbURI(org.exist.xmldb.XmldbURI) DocumentImpl(org.exist.dom.persistent.DocumentImpl) Permission(org.exist.security.Permission) XQueryContext(org.exist.xquery.XQueryContext) Nullable(javax.annotation.Nullable) InputSource(org.xml.sax.InputSource) LockedDocument(org.exist.dom.persistent.LockedDocument) AnyURIValue(org.exist.xquery.value.AnyURIValue) IOException(java.io.IOException) Try(com.evolvedbinary.j8fu.Try.Try) URLSource(org.exist.source.URLSource) SAXException(org.xml.sax.SAXException) SourceFactory(org.exist.source.SourceFactory) Optional(java.util.Optional) Sequence(org.exist.xquery.value.Sequence) Pattern(java.util.regex.Pattern) SAXAdapter(org.exist.dom.memtree.SAXAdapter) XPathException(org.exist.xquery.XPathException) InputStream(java.io.InputStream) XPathException(org.exist.xquery.XPathException) LockedDocument(org.exist.dom.persistent.LockedDocument) PermissionDeniedException(org.exist.security.PermissionDeniedException) LockMode(org.exist.storage.lock.Lock.LockMode) DocumentImpl(org.exist.dom.persistent.DocumentImpl) NodeProxy(org.exist.dom.persistent.NodeProxy) XmldbURI(org.exist.xmldb.XmldbURI)

Example 4 with LockMode

use of org.exist.storage.lock.Lock.LockMode in project exist by eXist-db.

the class LockTableUtils method stateToXml.

public static void stateToXml(final LockTable lockTable, final boolean includeStack, final Writer writer) throws XMLStreamException {
    final GregorianCalendar cal = new GregorianCalendar();
    final Map<String, Map<LockType, List<LockModeOwner>>> attempting = lockTable.getAttempting();
    final Map<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquired = lockTable.getAcquired();
    final XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
    final XMLStreamWriter xmlWriter = outputFactory.createXMLStreamWriter(writer);
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("lock-table");
    final XMLGregorianCalendar xmlCal = TimeUtils.getInstance().newXMLGregorianCalendar(cal);
    xmlWriter.writeAttribute("timestamp", xmlCal.toXMLFormat());
    // acquired locks
    xmlWriter.writeStartElement("acquired");
    for (final Map.Entry<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquire : acquired.entrySet()) {
        xmlWriter.writeStartElement("lock");
        xmlWriter.writeAttribute("id", acquire.getKey());
        for (final Map.Entry<LockType, Map<LockMode, Map<String, LockCountTraces>>> type : acquire.getValue().entrySet()) {
            xmlWriter.writeStartElement("type");
            xmlWriter.writeAttribute("id", type.getKey().name());
            for (final Map.Entry<LockMode, Map<String, LockCountTraces>> lockModeOwners : type.getValue().entrySet()) {
                xmlWriter.writeStartElement("mode");
                xmlWriter.writeAttribute("id", lockModeOwners.getKey().name());
                for (final Map.Entry<String, LockCountTraces> ownerHoldCount : lockModeOwners.getValue().entrySet()) {
                    xmlWriter.writeStartElement("thread");
                    xmlWriter.writeAttribute("id", ownerHoldCount.getKey());
                    final LockCountTraces holdCount = ownerHoldCount.getValue();
                    xmlWriter.writeAttribute("hold-count", Integer.toString(holdCount.count));
                    if (holdCount.traces != null && includeStack) {
                        for (int i = 0; i < holdCount.traces.size(); i++) {
                            xmlWriter.writeStartElement("stack-trace");
                            xmlWriter.writeAttribute("index", Integer.toString(i));
                            final StackTraceElement[] trace = holdCount.traces.get(i);
                            for (int j = 0; j < trace.length; j++) {
                                xmlWriter.writeStartElement("call");
                                final StackTraceElement call = trace[j];
                                xmlWriter.writeAttribute("index", Integer.toString(j));
                                xmlWriter.writeAttribute("class", call.getClassName());
                                xmlWriter.writeAttribute("method", call.getMethodName());
                                xmlWriter.writeAttribute("file", call.getFileName());
                                xmlWriter.writeAttribute("line", Integer.toString(call.getLineNumber()));
                                xmlWriter.writeCharacters(call.toString());
                                xmlWriter.writeEndElement();
                            }
                            xmlWriter.writeEndElement();
                        }
                    }
                    xmlWriter.writeEndElement();
                }
                xmlWriter.writeEndElement();
            }
            xmlWriter.writeEndElement();
        }
        xmlWriter.writeEndElement();
    }
    xmlWriter.writeEndElement();
    // attempting locks
    xmlWriter.writeStartElement("attempting");
    for (final Map.Entry<String, Map<Lock.LockType, List<LockTable.LockModeOwner>>> attempt : attempting.entrySet()) {
        xmlWriter.writeStartElement("lock");
        xmlWriter.writeAttribute("id", attempt.getKey());
        for (final Map.Entry<Lock.LockType, List<LockTable.LockModeOwner>> type : attempt.getValue().entrySet()) {
            xmlWriter.writeStartElement("type");
            xmlWriter.writeAttribute("id", type.getKey().name());
            for (final LockTable.LockModeOwner lockModeOwner : type.getValue()) {
                xmlWriter.writeStartElement("mode");
                xmlWriter.writeAttribute("id", lockModeOwner.getLockMode().name());
                xmlWriter.writeStartElement("thread");
                xmlWriter.writeAttribute("id", lockModeOwner.getOwnerThread());
                if (lockModeOwner.trace != null && includeStack) {
                    xmlWriter.writeStartElement("stack-trace");
                    for (int i = 0; i < lockModeOwner.trace.length; i++) {
                        xmlWriter.writeStartElement("call");
                        final StackTraceElement call = lockModeOwner.trace[i];
                        xmlWriter.writeAttribute("index", Integer.toString(i));
                        xmlWriter.writeAttribute("class", call.getClassName());
                        xmlWriter.writeAttribute("method", call.getMethodName());
                        xmlWriter.writeAttribute("file", call.getFileName());
                        xmlWriter.writeAttribute("line", Integer.toString(call.getLineNumber()));
                        xmlWriter.writeCharacters(call.toString());
                        xmlWriter.writeEndElement();
                    }
                    xmlWriter.writeEndElement();
                }
                xmlWriter.writeEndElement();
                xmlWriter.writeEndElement();
            }
            xmlWriter.writeEndElement();
        }
        xmlWriter.writeEndElement();
    }
    xmlWriter.writeEndElement();
    xmlWriter.writeEndElement();
    xmlWriter.writeEndDocument();
}
Also used : XMLOutputFactory(javax.xml.stream.XMLOutputFactory) LockType(org.exist.storage.lock.Lock.LockType) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) LockModeOwner(org.exist.storage.lock.LockTable.LockModeOwner) List(java.util.List) LockCountTraces(org.exist.storage.lock.LockTable.LockCountTraces) LockModeOwner(org.exist.storage.lock.LockTable.LockModeOwner) GregorianCalendar(java.util.GregorianCalendar) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) LockMode(org.exist.storage.lock.Lock.LockMode) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) Map(java.util.Map)

Example 5 with LockMode

use of org.exist.storage.lock.Lock.LockMode in project exist by eXist-db.

the class LockTableUtils method stateToString.

public static String stateToString(final LockTable lockTable, final boolean includeStack) {
    final Map<String, Map<LockType, List<LockModeOwner>>> attempting = lockTable.getAttempting();
    final Map<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquired = lockTable.getAcquired();
    final StringBuilder builder = new StringBuilder();
    builder.append(EOL).append("Acquired Locks").append(EOL).append("------------------------------------").append(EOL);
    for (final Map.Entry<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquire : acquired.entrySet()) {
        builder.append(acquire.getKey()).append(EOL);
        for (final Map.Entry<LockType, Map<LockMode, Map<String, LockCountTraces>>> type : acquire.getValue().entrySet()) {
            builder.append('\t').append(type.getKey()).append(EOL);
            for (final Map.Entry<LockMode, Map<String, LockCountTraces>> lockModeOwners : type.getValue().entrySet()) {
                builder.append("\t\t").append(lockModeOwners.getKey()).append('\t');
                boolean firstOwner = true;
                for (final Map.Entry<String, LockCountTraces> ownerHoldCount : lockModeOwners.getValue().entrySet()) {
                    if (!firstOwner) {
                        builder.append(", ");
                    } else {
                        firstOwner = false;
                    }
                    final LockCountTraces holdCount = ownerHoldCount.getValue();
                    builder.append(ownerHoldCount.getKey()).append(" (count=").append(holdCount.count).append(")");
                    if (holdCount.traces != null && includeStack) {
                        for (int i = 0; i < holdCount.traces.size(); i++) {
                            final StackTraceElement[] trace = holdCount.traces.get(i);
                            builder.append(EOL).append("\t\t\tTrace ").append(i).append(": ").append(EOL);
                            for (StackTraceElement stackTraceElement : trace) {
                                builder.append("\t\t\t\t").append(stackTraceElement).append(EOL);
                            }
                        }
                    }
                }
                builder.append(EOL);
            }
        }
    }
    builder.append(EOL).append(EOL);
    builder.append("Attempting Locks").append(EOL).append("------------------------------------").append(EOL);
    for (final Map.Entry<String, Map<Lock.LockType, List<LockTable.LockModeOwner>>> attempt : attempting.entrySet()) {
        builder.append(attempt.getKey()).append(EOL);
        for (final Map.Entry<Lock.LockType, List<LockTable.LockModeOwner>> type : attempt.getValue().entrySet()) {
            builder.append('\t').append(type.getKey()).append(EOL);
            for (final LockTable.LockModeOwner lockModeOwner : type.getValue()) {
                builder.append("\t\t").append(lockModeOwner.getLockMode()).append('\t').append(lockModeOwner.getOwnerThread());
                if (lockModeOwner.trace != null && includeStack) {
                    builder.append(EOL).append("\t\t\tTrace ").append(": ").append(EOL);
                    for (int i = 0; i < lockModeOwner.trace.length; i++) {
                        builder.append("\t\t\t\t").append(lockModeOwner.trace[i]).append(EOL);
                    }
                }
                builder.append(EOL);
            }
        }
    }
    return builder.toString();
}
Also used : LockCountTraces(org.exist.storage.lock.LockTable.LockCountTraces) LockModeOwner(org.exist.storage.lock.LockTable.LockModeOwner) LockMode(org.exist.storage.lock.Lock.LockMode) LockType(org.exist.storage.lock.Lock.LockType) LockModeOwner(org.exist.storage.lock.LockTable.LockModeOwner) List(java.util.List) Map(java.util.Map)

Aggregations

LockMode (org.exist.storage.lock.Lock.LockMode)7 Collection (org.exist.collections.Collection)4 XmldbURI (org.exist.xmldb.XmldbURI)4 IOException (java.io.IOException)3 EXistException (org.exist.EXistException)3 PermissionDeniedException (org.exist.security.PermissionDeniedException)3 URISyntaxException (java.net.URISyntaxException)2 List (java.util.List)2 Map (java.util.Map)2 TriggerException (org.exist.collections.triggers.TriggerException)2 DocumentImpl (org.exist.dom.persistent.DocumentImpl)2 DBBroker (org.exist.storage.DBBroker)2 LockType (org.exist.storage.lock.Lock.LockType)2 LockCountTraces (org.exist.storage.lock.LockTable.LockCountTraces)2 LockModeOwner (org.exist.storage.lock.LockTable.LockModeOwner)2 TransactionManager (org.exist.storage.txn.TransactionManager)2 Txn (org.exist.storage.txn.Txn)2 Try (com.evolvedbinary.j8fu.Try.Try)1 InputStream (java.io.InputStream)1 java.net (java.net)1