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

apoc.cluster.Cluster Maven / Gradle / Ivy

There is a newer version: 4.4.0.35
Show newest version
package apoc.cluster;

import apoc.Description;
import apoc.result.GraphResult;
import apoc.result.VirtualNode;
import apoc.result.VirtualRelationship;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.helpers.AdvertisedSocketAddress;
import org.neo4j.kernel.configuration.BoltConnector;
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.internal.GraphDatabaseAPI;
import org.neo4j.procedure.Context;
import org.neo4j.procedure.Procedure;

import static java.util.Collections.singletonMap;

public class Cluster
{
    @Context
    public GraphDatabaseService db;
    @Context
    public GraphDatabaseAPI api;

    public static final String boltAddressKey = "bolt_address";
    public static final Map shortName = new HashMap()
    {{
        put( "LEADER", "L" );
        put( "FOLLOWER", "F" );
        put( "READ_REPLICA", "RR" );
    }};

    @Procedure
    @Deprecated
    @Description( "apoc.cluster.graph - visually displays the servers participating in the Causal Cluster, their " +
            "roles, and which server in the cluster you are connected to." )
    public Stream graph()
    {
        Result execute = db.execute( "CALL dbms.cluster.overview()" );
        List servers = new LinkedList<>();
        List relationships = new LinkedList<>();

        while ( execute.hasNext() )
        {
            Map next = execute.next();
            String role = (String) next.get( "role" );
            String id = (String) next.get( "id" );
            Label roleLabel = Label.label( role );
            String[] addresses = ((List) next.get( "addresses" )).toArray( new String[0] );
            Map properties = new HashMap<>();
            properties.put( "name", shortName.get( role ) );
            properties.put( "title", role );
            properties.put( boltAddressKey, addresses[0] );
            properties.put( "http_address", addresses[1] );
            properties.put( "cluster_id", id );
            Node server = new VirtualNode( new Label[]{roleLabel}, properties, db );
            servers.add( server );
        }

        Optional leaderNode = getLeaderNode( servers );
        if ( leaderNode.isPresent() )
        {
            for ( Node server : servers )
            {
                if ( server.hasLabel( Label.label( "FOLLOWER" ) ) )
                {
                    VirtualRelationship follows =
                            new VirtualRelationship( server, leaderNode.get(), RelationshipType.withName( "FOLLOWS" ) );
                    relationships.add( follows );
                }
            }
        }

        VirtualNode client =
                new VirtualNode( new Label[]{Label.label( "CLIENT" )}, singletonMap( "name", "Client" ), db );
        Optional clientConnection = determineClientConnection( servers, client );
        if ( clientConnection.isPresent() )
        {
            servers.add( client );
            relationships.add( clientConnection.get() );
        }

        GraphResult graphResult = new GraphResult( servers, relationships );
        return Stream.of( graphResult );
    }

    private Optional determineClientConnection( List servers, Node client )
    {
        Optional boltAddress = getBoltConnector();
        if ( boltAddress.isPresent() )
        {
            for ( Node server : servers )
            {
                if ( serverHasBoltAddress( boltAddress.get(), server ) )
                {
                    return Optional.of( new VirtualRelationship( client, server,
                            RelationshipType.withName( "CONNECTED_TO" ) ) );
                }
            }
        }
        return Optional.empty();
    }

    private Optional getBoltConnector()
    {
        Config config = api.getDependencyResolver().resolveDependency( Config.class );
        final Optional boltConnector = config.enabledBoltConnectors().stream().findFirst();
        if ( boltConnector.isPresent() )
        {
            AdvertisedSocketAddress from = boltConnector.get().advertised_address.from( config );
            return Optional.of( "bolt://" + from );
        }
        return Optional.empty();
    }

    private boolean serverHasBoltAddress( String boltAddress, Node server )
    {
        String address = (String) server.getProperty( boltAddressKey );
        return address.equals( boltAddress );
    }


    private Optional getLeaderNode( List servers )
    {
        for ( Node server : servers )
        {
            if ( server.hasLabel( Label.label( "LEADER" ) ) )
            {
                return Optional.of( server );
            }
        }
        return Optional.empty();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy