Search in sources :

Example 1 with IndexEntry

use of org.janusgraph.diskstorage.indexing.IndexEntry in project janusgraph by JanusGraph.

the class StandardTransactionLogProcessor method restoreExternalIndexes.

private void restoreExternalIndexes(Predicate<String> isFailedIndex, TransactionLogHeader.Entry entry) {
    // 1) Collect all elements (vertices and relations) and the indexes for which they need to be restored
    SetMultimap<String, IndexRestore> indexRestores = HashMultimap.create();
    BackendOperation.execute(() -> {
        final StandardJanusGraphTx tx = (StandardJanusGraphTx) graph.newTransaction();
        try {
            entry.getContentAsModifications(serializer).stream().map(m -> ModificationDeserializer.parseRelation(m, tx)).forEach(rel -> {
                // Collect affected vertex indexes
                for (final MixedIndexType index : getMixedIndexes(rel.getType())) {
                    if (index.getElement() == ElementCategory.VERTEX && isFailedIndex.apply(index.getBackingIndexName())) {
                        assert rel.isProperty();
                        indexRestores.put(index.getBackingIndexName(), new IndexRestore(rel.getVertex(0).longId(), ElementCategory.VERTEX, getIndexId(index)));
                    }
                }
                // See if relation itself is affected
                for (final RelationType relType : rel.getPropertyKeysDirect()) {
                    for (final MixedIndexType index : getMixedIndexes(relType)) {
                        if (index.getElement().isInstance(rel) && isFailedIndex.apply(index.getBackingIndexName())) {
                            assert rel.id() instanceof RelationIdentifier;
                            indexRestores.put(index.getBackingIndexName(), new IndexRestore(rel.id(), ElementCategory.getByClazz(rel.getClass()), getIndexId(index)));
                        }
                    }
                }
            });
        } finally {
            if (tx.isOpen())
                tx.rollback();
        }
        return true;
    }, readTime);
    // 2) Restore elements per backing index
    for (final String indexName : indexRestores.keySet()) {
        final StandardJanusGraphTx tx = (StandardJanusGraphTx) graph.newTransaction();
        try {
            BackendTransaction btx = tx.getTxHandle();
            final IndexTransaction indexTx = btx.getIndexTransaction(indexName);
            BackendOperation.execute(new Callable<Boolean>() {

                @Override
                public Boolean call() throws Exception {
                    Map<String, Map<String, List<IndexEntry>>> restoredDocs = Maps.newHashMap();
                    indexRestores.get(indexName).forEach(restore -> {
                        JanusGraphSchemaVertex indexV = (JanusGraphSchemaVertex) tx.getVertex(restore.indexId);
                        MixedIndexType index = (MixedIndexType) indexV.asIndexType();
                        JanusGraphElement element = restore.retrieve(tx);
                        if (element != null) {
                            graph.getIndexSerializer().reindexElement(element, index, restoredDocs);
                        } else {
                            // Element is deleted
                            graph.getIndexSerializer().removeElement(restore.elementId, index, restoredDocs);
                        }
                    });
                    indexTx.restore(restoredDocs);
                    indexTx.commit();
                    return true;
                }

                @Override
                public String toString() {
                    return "IndexMutation";
                }
            }, persistenceTime);
        } finally {
            if (tx.isOpen())
                tx.rollback();
        }
    }
}
Also used : SchemaSource(org.janusgraph.graphdb.types.SchemaSource) org.janusgraph.diskstorage.log(org.janusgraph.diskstorage.log) StandardJanusGraphTx(org.janusgraph.graphdb.transaction.StandardJanusGraphTx) BackgroundThread(org.janusgraph.util.system.BackgroundThread) BackendOperation(org.janusgraph.diskstorage.util.BackendOperation) LoggerFactory(org.slf4j.LoggerFactory) IndexTransaction(org.janusgraph.diskstorage.indexing.IndexTransaction) HashCodeBuilder(org.apache.commons.lang.builder.HashCodeBuilder) Callable(java.util.concurrent.Callable) IndexTypeWrapper(org.janusgraph.graphdb.types.indextype.IndexTypeWrapper) JanusGraphTransaction(org.janusgraph.core.JanusGraphTransaction) Future(java.util.concurrent.Future) Serializer(org.janusgraph.graphdb.database.serialize.Serializer) IndexEntry(org.janusgraph.diskstorage.indexing.IndexEntry) Duration(java.time.Duration) Map(java.util.Map) Predicates(com.google.common.base.Predicates) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) JanusGraphException(org.janusgraph.core.JanusGraphException) IndexType(org.janusgraph.graphdb.types.IndexType) com.google.common.collect(com.google.common.collect) LogTxStatus(org.janusgraph.graphdb.database.log.LogTxStatus) JanusGraphElement(org.janusgraph.core.JanusGraphElement) TransactionLogHeader(org.janusgraph.graphdb.database.log.TransactionLogHeader) TransactionRecovery(org.janusgraph.core.log.TransactionRecovery) RelationType(org.janusgraph.core.RelationType) Logger(org.slf4j.Logger) TimestampProvider(org.janusgraph.diskstorage.util.time.TimestampProvider) StandardJanusGraph(org.janusgraph.graphdb.database.StandardJanusGraph) JanusGraphSchemaVertex(org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex) LogTxMeta(org.janusgraph.graphdb.database.log.LogTxMeta) Instant(java.time.Instant) ElementCategory(org.janusgraph.graphdb.internal.ElementCategory) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) com.google.common.cache(com.google.common.cache) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) RelationIdentifier(org.janusgraph.graphdb.relations.RelationIdentifier) Predicate(com.google.common.base.Predicate) GraphDatabaseConfiguration(org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration) Preconditions(com.google.common.base.Preconditions) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) Collections(java.util.Collections) org.janusgraph.diskstorage(org.janusgraph.diskstorage) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) IndexTransaction(org.janusgraph.diskstorage.indexing.IndexTransaction) RelationIdentifier(org.janusgraph.graphdb.relations.RelationIdentifier) JanusGraphException(org.janusgraph.core.JanusGraphException) ExecutionException(java.util.concurrent.ExecutionException) JanusGraphElement(org.janusgraph.core.JanusGraphElement) StandardJanusGraphTx(org.janusgraph.graphdb.transaction.StandardJanusGraphTx) RelationType(org.janusgraph.core.RelationType) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType) JanusGraphSchemaVertex(org.janusgraph.graphdb.types.vertices.JanusGraphSchemaVertex) List(java.util.List) Map(java.util.Map)

Example 2 with IndexEntry

use of org.janusgraph.diskstorage.indexing.IndexEntry in project janusgraph by JanusGraph.

the class IndexRepairJob method process.

@Override
public void process(JanusGraphVertex vertex, ScanMetrics metrics) {
    try {
        BackendTransaction mutator = writeTx.getTxHandle();
        if (index instanceof RelationTypeIndex) {
            RelationTypeIndexWrapper wrapper = (RelationTypeIndexWrapper) index;
            InternalRelationType wrappedType = wrapper.getWrappedType();
            EdgeSerializer edgeSerializer = writeTx.getEdgeSerializer();
            List<Entry> additions = new ArrayList<>();
            for (Object relation : vertex.query().types(indexRelationTypeName).direction(Direction.OUT).relations()) {
                InternalRelation janusgraphRelation = (InternalRelation) relation;
                for (int pos = 0; pos < janusgraphRelation.getArity(); pos++) {
                    if (!wrappedType.isUnidirected(Direction.BOTH) && !wrappedType.isUnidirected(EdgeDirection.fromPosition(pos)))
                        // Directionality is not covered
                        continue;
                    Entry entry = edgeSerializer.writeRelation(janusgraphRelation, wrappedType, pos, writeTx);
                    additions.add(entry);
                }
            }
            StaticBuffer vertexKey = writeTx.getIdInspector().getKey(vertex.longId());
            mutator.mutateEdges(vertexKey, additions, KCVSCache.NO_DELETIONS);
            metrics.incrementCustom(ADDED_RECORDS_COUNT, additions.size());
        } else if (index instanceof JanusGraphIndex) {
            IndexType indexType = managementSystem.getSchemaVertex(index).asIndexType();
            assert indexType != null;
            IndexSerializer indexSerializer = graph.getIndexSerializer();
            // Gather elements to index
            List<JanusGraphElement> elements;
            switch(indexType.getElement()) {
                case VERTEX:
                    elements = ImmutableList.of(vertex);
                    break;
                case PROPERTY:
                    elements = Lists.newArrayList();
                    for (JanusGraphVertexProperty p : addIndexSchemaConstraint(vertex.query(), indexType).properties()) {
                        elements.add(p);
                    }
                    break;
                case EDGE:
                    elements = Lists.newArrayList();
                    for (Object e : addIndexSchemaConstraint(vertex.query().direction(Direction.OUT), indexType).edges()) {
                        elements.add((JanusGraphEdge) e);
                    }
                    break;
                default:
                    throw new AssertionError("Unexpected category: " + indexType.getElement());
            }
            if (indexType.isCompositeIndex()) {
                for (JanusGraphElement element : elements) {
                    Set<IndexSerializer.IndexUpdate<StaticBuffer, Entry>> updates = indexSerializer.reindexElement(element, (CompositeIndexType) indexType);
                    for (IndexSerializer.IndexUpdate<StaticBuffer, Entry> update : updates) {
                        log.debug("Mutating index {}: {}", indexType, update.getEntry());
                        mutator.mutateIndex(update.getKey(), Lists.newArrayList(update.getEntry()), KCVSCache.NO_DELETIONS);
                        metrics.incrementCustom(ADDED_RECORDS_COUNT);
                    }
                }
            } else {
                assert indexType.isMixedIndex();
                Map<String, Map<String, List<IndexEntry>>> documentsPerStore = new HashMap<>();
                for (JanusGraphElement element : elements) {
                    indexSerializer.reindexElement(element, (MixedIndexType) indexType, documentsPerStore);
                    metrics.incrementCustom(DOCUMENT_UPDATES_COUNT);
                }
                mutator.getIndexTransaction(indexType.getBackingIndexName()).restore(documentsPerStore);
            }
        } else
            throw new UnsupportedOperationException("Unsupported index found: " + index);
    } catch (final Exception e) {
        managementSystem.rollback();
        writeTx.rollback();
        metrics.incrementCustom(FAILED_TX);
        throw new JanusGraphException(e.getMessage(), e);
    }
}
Also used : InternalRelation(org.janusgraph.graphdb.internal.InternalRelation) IndexEntry(org.janusgraph.diskstorage.indexing.IndexEntry) Entry(org.janusgraph.diskstorage.Entry) EdgeSerializer(org.janusgraph.graphdb.database.EdgeSerializer) RelationTypeIndexWrapper(org.janusgraph.graphdb.database.management.RelationTypeIndexWrapper) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) ImmutableList(com.google.common.collect.ImmutableList) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) IndexType(org.janusgraph.graphdb.types.IndexType) CompositeIndexType(org.janusgraph.graphdb.types.CompositeIndexType) BackendTransaction(org.janusgraph.diskstorage.BackendTransaction) MixedIndexType(org.janusgraph.graphdb.types.MixedIndexType) IndexSerializer(org.janusgraph.graphdb.database.IndexSerializer) CompositeIndexType(org.janusgraph.graphdb.types.CompositeIndexType) InternalRelationType(org.janusgraph.graphdb.internal.InternalRelationType)

Example 3 with IndexEntry

use of org.janusgraph.diskstorage.indexing.IndexEntry in project janusgraph by JanusGraph.

the class ElasticSearchIndex method getDeletionScript.

private String getDeletionScript(KeyInformation.IndexRetriever information, String storeName, IndexMutation mutation) throws PermanentBackendException {
    final StringBuilder script = new StringBuilder();
    final String INDEX_NAME = "index";
    int i = 0;
    for (final IndexEntry deletion : mutation.getDeletions()) {
        final KeyInformation keyInformation = information.get(storeName).get(deletion.field);
        switch(keyInformation.getCardinality()) {
            case SINGLE:
                script.append("ctx._source.remove(\"").append(deletion.field).append("\");");
                if (hasDualStringMapping(information.get(storeName, deletion.field))) {
                    script.append("ctx._source.remove(\"").append(getDualMappingName(deletion.field)).append("\");");
                }
                break;
            case SET:
            case LIST:
                final String jsValue = convertToJsType(deletion.value, compat.scriptLang(), Mapping.getMapping(keyInformation));
                String index = INDEX_NAME + i++;
                script.append("def ").append(index).append(" = ctx._source[\"").append(deletion.field).append("\"].indexOf(").append(jsValue).append("); ctx._source[\"").append(deletion.field).append("\"].remove(").append(index).append(");");
                if (hasDualStringMapping(information.get(storeName, deletion.field))) {
                    index = INDEX_NAME + i++;
                    script.append("def ").append(index).append(" = ctx._source[\"").append(getDualMappingName(deletion.field)).append("\"].indexOf(").append(jsValue).append("); ctx._source[\"").append(getDualMappingName(deletion.field)).append("\"].remove(").append(index).append(");");
                }
                break;
        }
    }
    return script.toString();
}
Also used : IndexEntry(org.janusgraph.diskstorage.indexing.IndexEntry) KeyInformation(org.janusgraph.diskstorage.indexing.KeyInformation)

Example 4 with IndexEntry

use of org.janusgraph.diskstorage.indexing.IndexEntry in project janusgraph by JanusGraph.

the class ElasticSearchIndex method getAdditionScript.

private String getAdditionScript(KeyInformation.IndexRetriever information, String storeName, IndexMutation mutation) throws PermanentBackendException {
    final StringBuilder script = new StringBuilder();
    for (final IndexEntry e : mutation.getAdditions()) {
        final KeyInformation keyInformation = information.get(storeName).get(e.field);
        switch(keyInformation.getCardinality()) {
            case SET:
            case LIST:
                script.append("if(ctx._source[\"").append(e.field).append("\"] == null) ctx._source[\"").append(e.field).append("\"] = [];");
                script.append("ctx._source[\"").append(e.field).append("\"].add(").append(convertToJsType(e.value, compat.scriptLang(), Mapping.getMapping(keyInformation))).append(");");
                if (hasDualStringMapping(keyInformation)) {
                    script.append("if(ctx._source[\"").append(getDualMappingName(e.field)).append("\"] == null) ctx._source[\"").append(getDualMappingName(e.field)).append("\"] = [];");
                    script.append("ctx._source[\"").append(getDualMappingName(e.field)).append("\"].add(").append(convertToJsType(e.value, compat.scriptLang(), Mapping.getMapping(keyInformation))).append(");");
                }
                break;
            default:
                break;
        }
    }
    return script.toString();
}
Also used : IndexEntry(org.janusgraph.diskstorage.indexing.IndexEntry) KeyInformation(org.janusgraph.diskstorage.indexing.KeyInformation)

Example 5 with IndexEntry

use of org.janusgraph.diskstorage.indexing.IndexEntry in project janusgraph by JanusGraph.

the class SolrIndex method restore.

@Override
public void restore(Map<String, Map<String, List<IndexEntry>>> documents, KeyInformation.IndexRetriever information, BaseTransaction tx) throws BackendException {
    try {
        for (final Map.Entry<String, Map<String, List<IndexEntry>>> stores : documents.entrySet()) {
            final String collectionName = stores.getKey();
            final List<String> deleteIds = new ArrayList<>();
            final List<SolrInputDocument> newDocuments = new ArrayList<>();
            for (final Map.Entry<String, List<IndexEntry>> entry : stores.getValue().entrySet()) {
                final String docID = entry.getKey();
                final List<IndexEntry> content = entry.getValue();
                if (content == null || content.isEmpty()) {
                    if (logger.isTraceEnabled())
                        logger.trace("Deleting document [{}]", docID);
                    deleteIds.add(docID);
                    continue;
                }
                final SolrInputDocument doc = new SolrInputDocument();
                doc.setField(getKeyFieldId(collectionName), docID);
                final Map<String, Object> adds = collectFieldValues(content, collectionName, information);
                adds.forEach(doc::setField);
                newDocuments.add(doc);
            }
            commitDeletes(collectionName, deleteIds);
            commitChanges(collectionName, newDocuments);
        }
    } catch (final Exception e) {
        throw new TemporaryBackendException("Could not restore Solr index", e);
    }
}
Also used : ArrayList(java.util.ArrayList) IndexEntry(org.janusgraph.diskstorage.indexing.IndexEntry) SolrServerException(org.apache.solr.client.solrj.SolrServerException) UncheckedIOException(java.io.UncheckedIOException) TemporaryBackendException(org.janusgraph.diskstorage.TemporaryBackendException) BackendException(org.janusgraph.diskstorage.BackendException) KeeperException(org.apache.zookeeper.KeeperException) IOException(java.io.IOException) PermanentBackendException(org.janusgraph.diskstorage.PermanentBackendException) SolrInputDocument(org.apache.solr.common.SolrInputDocument) TemporaryBackendException(org.janusgraph.diskstorage.TemporaryBackendException) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

IndexEntry (org.janusgraph.diskstorage.indexing.IndexEntry)9 KeyInformation (org.janusgraph.diskstorage.indexing.KeyInformation)5 HashMap (java.util.HashMap)4 Map (java.util.Map)4 IOException (java.io.IOException)3 UncheckedIOException (java.io.UncheckedIOException)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 SolrInputDocument (org.apache.solr.common.SolrInputDocument)3 BackendException (org.janusgraph.diskstorage.BackendException)3 PermanentBackendException (org.janusgraph.diskstorage.PermanentBackendException)3 Preconditions (com.google.common.base.Preconditions)2 ImmutableList (com.google.common.collect.ImmutableList)2 Instant (java.time.Instant)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 SolrServerException (org.apache.solr.client.solrj.SolrServerException)2 KeeperException (org.apache.zookeeper.KeeperException)2 TemporaryBackendException (org.janusgraph.diskstorage.TemporaryBackendException)2 IndexMutation (org.janusgraph.diskstorage.indexing.IndexMutation)2 InternalRelationType (org.janusgraph.graphdb.internal.InternalRelationType)2