All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.neo4j.dbms.systemgraph.CommunityTopologyGraphDbmsModel Maven / Gradle / Ivy

Go to download

Neo4j kernel is a lightweight, embedded Java database designed to store data structured as graphs rather than tables. For more information, see http://neo4j.org.

There is a newer version: 5.25.1
Show newest version
/*
 * Copyright (c) "Neo4j"
 * Neo4j Sweden AB [https://neo4j.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.neo4j.dbms.systemgraph;

import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.database.DatabaseReference;
import org.neo4j.kernel.database.DatabaseReferenceImpl;
import org.neo4j.kernel.database.NamedDatabaseId;
import org.neo4j.kernel.database.NormalizedDatabaseName;

public class CommunityTopologyGraphDbmsModel implements TopologyGraphDbmsModel {
    protected final Transaction tx;

    public CommunityTopologyGraphDbmsModel(Transaction tx) {
        this.tx = tx;
    }

    public Map getAllDatabaseAccess() {
        try (ResourceIterator nodes = tx.findNodes(DATABASE_LABEL)) {
            return nodes.stream()
                    .collect(Collectors.toMap(
                            CommunityTopologyGraphDbmsModelUtil::getDatabaseId,
                            CommunityTopologyGraphDbmsModelUtil::getDatabaseAccess));
        }
    }

    @Override
    public Optional getDatabaseIdByAlias(String databaseName) {
        return CommunityTopologyGraphDbmsModelUtil.getDatabaseIdByAlias(tx, databaseName)
                .or(() ->
                        CommunityTopologyGraphDbmsModelUtil.getDatabaseIdBy(tx, DATABASE_NAME_PROPERTY, databaseName));
    }

    @Override
    public Optional getDatabaseIdByUUID(UUID uuid) {
        return CommunityTopologyGraphDbmsModelUtil.getDatabaseIdBy(tx, DATABASE_UUID_PROPERTY, uuid.toString());
    }

    @Override
    public Set getAllDatabaseReferences() {
        var primaryRefs = CommunityTopologyGraphDbmsModelUtil.getAllPrimaryStandardDatabaseReferencesInRoot(tx);
        var internalAliasRefs = getAllInternalDatabaseReferencesInRoot();
        var externalRefs = getAllExternalDatabaseReferencesInRoot();
        var compositeRefs = getAllCompositeDatabaseReferencesInRoot();
        var shardedPropertyRefs = getAllShardedPropertyDatabaseReferencesInRoot();
        return Stream.of(primaryRefs, internalAliasRefs, externalRefs, compositeRefs, shardedPropertyRefs)
                .flatMap(s -> s)
                .collect(Collectors.toUnmodifiableSet());
    }

    @Override
    public Set getAllInternalDatabaseReferences() {
        var primaryRefs = CommunityTopologyGraphDbmsModelUtil.getAllPrimaryStandardDatabaseReferencesInRoot(tx);
        var localAliasRefs = getAllInternalDatabaseReferencesInRoot();

        return Stream.concat(primaryRefs, localAliasRefs).collect(Collectors.toUnmodifiableSet());
    }

    @Override
    public Set getAllExternalDatabaseReferences() {
        return getAllExternalDatabaseReferencesInRoot().collect(Collectors.toUnmodifiableSet());
    }

    @Override
    public Set getAllCompositeDatabaseReferences() {
        return getAllCompositeDatabaseReferencesInRoot().collect(Collectors.toUnmodifiableSet());
    }

    @Override
    public Set getAllShardedPropertyDatabaseReferences() {
        return getAllShardedPropertyDatabaseReferencesInRoot().collect(Collectors.toUnmodifiableSet());
    }

    @Override
    public Optional getDatabaseRefByAlias(String databaseName) {
        // A uniqueness constraint at the Cypher level should prevent two references from ever having the same name, but
        // in case they do, we simply prefer the internal reference.
        return Optional.empty()
                .or(() -> getCompositeDatabaseReferenceInRoot(databaseName))
                .or(() -> getShardedPropertyDatabaseReferenceInRoot(databaseName))
                .or(() -> CommunityTopologyGraphDbmsModelUtil.getInternalDatabaseReference(tx, databaseName))
                .or(() -> CommunityTopologyGraphDbmsModelUtil.getExternalDatabaseReference(tx, databaseName));
    }

    @Override
    public Optional getDriverSettings(String databaseName, String namespace) {
        return tx.findNodes(REMOTE_DATABASE_LABEL, NAME_PROPERTY, databaseName, NAMESPACE_PROPERTY, namespace).stream()
                .findFirst()
                .flatMap(CommunityTopologyGraphDbmsModelUtil::getDriverSettings);
    }

    @Override
    public Optional> getAliasProperties(String databaseName, String namespace) {
        return tx.findNodes(DATABASE_NAME_LABEL, NAME_PROPERTY, databaseName, NAMESPACE_PROPERTY, namespace).stream()
                .findFirst()
                .flatMap(CommunityTopologyGraphDbmsModelUtil::getAliasProperties);
    }

    @Override
    public Optional getExternalDatabaseCredentials(
            DatabaseReferenceImpl.External databaseReference) {
        String databaseName = databaseReference.alias().name();
        String namespace =
                databaseReference.namespace().map(NormalizedDatabaseName::name).orElse(DEFAULT_NAMESPACE);
        return tx.findNodes(REMOTE_DATABASE_LABEL, NAME_PROPERTY, databaseName, NAMESPACE_PROPERTY, namespace).stream()
                .findFirst()
                .flatMap(CommunityTopologyGraphDbmsModelUtil::getDatabaseCredentials);
    }

    private Stream getAllCompositeDatabaseReferencesInRoot() {
        return getAliasNodesInNamespace(DATABASE_NAME_LABEL, DEFAULT_NAMESPACE)
                .flatMap(alias -> CommunityTopologyGraphDbmsModelUtil.getTargetedDatabaseNode(alias)
                        .filter(db -> db.hasLabel(COMPOSITE_DATABASE_LABEL))
                        .flatMap(db -> createCompositeReference(alias, db))
                        .stream());
    }

    private Optional getCompositeDatabaseReferenceInRoot(String databaseName) {
        return getAliasNodesInNamespace(DATABASE_NAME_LABEL, DEFAULT_NAMESPACE, databaseName)
                .flatMap(alias -> CommunityTopologyGraphDbmsModelUtil.getTargetedDatabaseNode(alias)
                        .filter(db -> db.hasLabel(COMPOSITE_DATABASE_LABEL))
                        .flatMap(db -> createCompositeReference(alias, db))
                        .stream())
                .findFirst();
    }

    private Optional createCompositeReference(Node alias, Node db) {
        return CommunityTopologyGraphDbmsModelUtil.ignoreConcurrentDeletes(() -> {
            var aliasName = CommunityTopologyGraphDbmsModelUtil.getNameProperty(DATABASE_NAME, alias);
            var databaseId = CommunityTopologyGraphDbmsModelUtil.getDatabaseId(db);
            var compositeName = CommunityTopologyGraphDbmsModelUtil.getNameProperty(DATABASE, db);
            var components = getAllDatabaseReferencesInComposite(compositeName);
            return Optional.of(new DatabaseReferenceImpl.Composite(aliasName, databaseId, components));
        });
    }

    private Stream getAllShardedPropertyDatabaseReferencesInRoot() {
        return getAliasNodesInNamespace(DATABASE_NAME_LABEL, DEFAULT_NAMESPACE)
                .flatMap(alias -> CommunityTopologyGraphDbmsModelUtil.getTargetedDatabaseNode(alias)
                        .filter(db -> db.hasProperty(DATABASE_SHARD_COUNT_PROPERTY))
                        .flatMap(db -> createShardedPropertyDatabaseReference(alias, db))
                        .stream());
    }

    private Optional getShardedPropertyDatabaseReferenceInRoot(String databaseName) {
        return getAliasNodesInNamespace(DATABASE_NAME_LABEL, DEFAULT_NAMESPACE, databaseName)
                .flatMap(alias -> CommunityTopologyGraphDbmsModelUtil.getTargetedDatabaseNode(alias)
                        .filter(db -> db.hasProperty(DATABASE_SHARD_COUNT_PROPERTY))
                        .flatMap(db -> createShardedPropertyDatabaseReference(alias, db))
                        .stream())
                .findFirst();
    }

    private Optional createShardedPropertyDatabaseReference(Node alias, Node db) {
        return CommunityTopologyGraphDbmsModelUtil.ignoreConcurrentDeletes(() -> {
            var aliasName = CommunityTopologyGraphDbmsModelUtil.getNameProperty(DATABASE_NAME, alias);
            var databaseId = CommunityTopologyGraphDbmsModelUtil.getDatabaseId(db);
            int shardCount = (int) db.getProperty(DATABASE_SHARD_COUNT_PROPERTY, 0);
            var shards = DatabaseReferenceImpl.SPD.createForShards(
                    aliasName.name(), shardCount, this::getDatabaseRefByAlias);
            return Optional.of(new DatabaseReferenceImpl.SPD(aliasName, databaseId, shards));
        });
    }

    private Stream getAliasNodesInNamespace(Label label, String namespace) {
        return tx.findNodes(label, NAMESPACE_PROPERTY, namespace).stream();
    }

    private Stream getAliasNodesInNamespace(Label label, String namespace, String databaseName) {
        return tx.findNodes(label, NAMESPACE_PROPERTY, namespace, NAME_PROPERTY, databaseName).stream();
    }

    private Set getAllDatabaseReferencesInComposite(NormalizedDatabaseName compositeName) {
        var internalRefs = getAllInternalDatabaseReferencesInNamespace(compositeName.name());
        var externalRefs = getAllExternalDatabaseReferencesInNamespace(compositeName.name());

        return Stream.concat(internalRefs, externalRefs).collect(Collectors.toUnmodifiableSet());
    }

    private Stream getAllExternalDatabaseReferencesInRoot() {
        return getAllExternalDatabaseReferencesInNamespace(DEFAULT_NAMESPACE);
    }

    private Stream getAllExternalDatabaseReferencesInNamespace(String namespace) {
        return getAliasNodesInNamespace(REMOTE_DATABASE_LABEL, namespace)
                .flatMap(alias -> CommunityTopologyGraphDbmsModelUtil.createExternalReference(alias).stream());
    }

    private Stream getAllInternalDatabaseReferencesInRoot() {
        return getAllInternalDatabaseReferencesInNamespace(DEFAULT_NAMESPACE);
    }

    private Stream getAllInternalDatabaseReferencesInNamespace(String namespace) {
        return getAliasNodesInNamespace(DATABASE_NAME_LABEL, namespace)
                .flatMap(alias -> CommunityTopologyGraphDbmsModelUtil.getTargetedDatabaseNode(alias)
                        .filter(node -> !node.hasProperty(DATABASE_VIRTUAL_PROPERTY))
                        .filter(node -> !node.hasProperty(DATABASE_SHARD_COUNT_PROPERTY))
                        .map(CommunityTopologyGraphDbmsModelUtil::getDatabaseId)
                        .flatMap(db -> CommunityTopologyGraphDbmsModelUtil.createInternalReference(alias, db))
                        .stream());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy