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

org.neo4j.dbms.database.SystemGraphComponent 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.database;

import org.neo4j.function.ThrowingConsumer;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.ResourceIterator;
import org.neo4j.graphdb.Transaction;
import org.neo4j.internal.kernel.api.security.SecurityContext;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.impl.coreapi.TransactionImpl;

/**
 * The system database is used to store information of interest to many parts of the DBMS. Each sub-graph can be thought of as being of primary interest to (or
 * managed by) a particular component of the DBMS. For example, the security sub-graph composed of User, Role, Privilege and various other related nodes and
 * relationships is primarily initialized, upgraded and read by the SecurityModule.
 * 

* This interface defines an external API to each component whereby external commands can ask about the current status of the component's sub-graph within the * system database, and also trigger upgrades (or migrations) of the sub-graph from an older version to the current version. *

* It is up to each component to define the rules for which older versions would be concurrently supported within any running DBMS. However, being supported * also means it is possible to upgrade to the current version. This means that if the detect method return REQUIRES_UPGRADE, then it * should be possible to call the upgradeToCurrent method and achieve the upgrade. */ public interface SystemGraphComponent { Label VERSION_LABEL = Label.label("Version"); /** * This should be a unique identifier for the component. It will be used in two places: *

    *
  1. A key in a map of components for managing upgrades of the entire DBMS
  2. *
  3. A property key for the Version node used to store versioning information for this component
  4. *
*/ Name componentName(); /** * Return the current status of this component. This involves reading the current contents of the system database and detecting whether the sub-graph * managed by this component is missing, old or up-to-date. Older sub-graphs could be supported for upgrade, or unsupported (in which case the server cannot * be started). */ Status detect(Transaction tx); default Status detect(GraphDatabaseService system) { try (Transaction tx = system.beginTx()) { SystemGraphComponent.Status status = detect(tx); tx.commit(); return status; } } /** * If the component-specific sub-graph of the system database is not initialized yet (empty), this method should populate it with the default contents for * the current version of the component. * * @throws Exception on any possible error raised by the initialization process */ void initializeSystemGraph(GraphDatabaseService system, boolean firstInitialization) throws Exception; /** * If the component-specific sub-graph of the system database is an older, but still supported, version, this method should upgrade it to the latest * supported version. * * @throws Exception on any possible error raised by the upgrade process */ void upgradeToCurrent(GraphDatabaseService system) throws Exception; /** * Delete unused parts of the system graph. */ default void cleanup(GraphDatabaseService system) throws Exception {} static void executeWithFullAccess(GraphDatabaseService system, ThrowingConsumer consumer) throws Exception { try (TransactionImpl tx = (TransactionImpl) system.beginTx(); KernelTransaction.Revertable ignore = tx.kernelTransaction().overrideWith(SecurityContext.AUTH_DISABLED)) { consumer.accept(tx); tx.commit(); } } default Integer getVersion(Transaction tx, Name componentVersionProperty) { return getVersionNumber(tx, componentVersionProperty); } /** * Get the version number of a component from the system graph. * * @param tx an open transaction * @param componentName name of the property describing the version for the component * @return The version of the component or null if there is no stored information. */ static Integer getVersionNumber(Transaction tx, Name componentName) { Integer result = null; try (ResourceIterator nodes = tx.findNodes(VERSION_LABEL)) { if (nodes.hasNext()) { Node versionNode = nodes.next(); result = (Integer) versionNode.getProperty(componentName.name(), null); } } return result; } enum Status { UNINITIALIZED("No sub-graph detected for this component", "requires initialization"), CURRENT("The sub-graph is already at the current version", "nothing to do"), REQUIRES_UPGRADE( "The sub-graph is supported, but is an older version and requires upgrade", "CALL dbms.upgrade()"), UNSUPPORTED_BUT_CAN_UPGRADE( "The sub-graph is unsupported, this component cannot function", "Restart Neo4j in single-instance mode to upgrade this component at startup"), UNSUPPORTED( "The sub-graph is unsupported because it is too old, this component cannot function", "Downgrade Neo4j and then upgrade this component before upgrading Neo4j again"), UNSUPPORTED_FUTURE( "The sub-graph is unsupported because it is a newer version, this component cannot function", "Upgrade Neo4j"); private final String description; private final String resolution; Status(String description, String resolution) { this.description = description; this.resolution = resolution; } /** * Combine status's to present an overall status for the entire DBMS. Primarily we care about two cases: *
    *
  • If any component is unsupported, the entire DBMS is unsupported
  • *
  • If any component requires an upgrade, the entire DBMS requires an upgrade
  • *
* Initialization is handled through a different code path and so does not require handling here. */ public Status with(Status other) { Status[] precedence = new Status[] { UNSUPPORTED_FUTURE, UNSUPPORTED, UNSUPPORTED_BUT_CAN_UPGRADE, REQUIRES_UPGRADE, UNINITIALIZED, CURRENT }; for (Status status : precedence) { if (other == status || this == status) { return status; } } return this; } public String description() { return description; } public String resolution() { return resolution; } } record Name(String name) { @Override public String toString() { return name; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy