-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[gRNAet7B] Fixes trigger procedures in clusters for neo4j 5.x (#250)
* [gRNAet7B] Fixes trigger procedures in clusters (#3183) * [gRNAet7B] Leaves it working for add trigger * [gRNAet7B] Fixes trigger procedures with split LifeCycle and System utils * Deprecated old triggers and included warning - Added check to fail if they are executed against a system = FOLLOWER * Added cluster tests * removed unused import * changed msg wording * split deprecated and new triggers * Fixed TriggerExtendedTest * update apoc.systemdb.export.metadata * remove lastUpdate, rename classes * added eventual consistency * commonize trigger new and deprec. cache * ignored tests * added eventually separated tests - restored util.validateQuery - small changes * renamed Trigger classes * var names - test changes and additions * nitpick and lightened test * test flaky cluster Co-authored-by: Giuseppe Villani <[email protected]> * [gRNAet7B] Trigger procedures neo4j 5.x changes * [gRNAet7B] code clean - removed unused import * [gRNAet7B] Try fix flaky TriggerClusterRoutingTest (neo4j-contrib/neo4j-apoc-procedures#3323) * [gRNAet7B] fix some tests * [gRNAet7B] fix TriggerClusterRoutingTest * [gRNAet7B] fix TriggerRouting error message * [gRNAet7B] Added trigger show procedure (neo4j-contrib/neo4j-apoc-procedures#3335) * Fix flaky trigger dbms availability tests * added apoc.trigger.show proc * retry to fix flaky test by separating setLastUpdate() * removed updated output - some code refactoring * split pr - changes review * removed inner transaction * updated documentation * reset wrong generated docs * Added admin in trigger.show * small adoc changes * [gRNAet7B] Try de-flaky some tests with new procedure triggers (neo4j-contrib/neo4j-apoc-procedures#3355) * Try de-flaky some tests with new procedure triggers * moved TriggerTestUtil and increased trigger.refresh value * added waitDbsAvailable util * [gRNAet7B] removed unused import * [gRNAet7B] fix cluster test * [gRNAet7B] added documentation about new trigger procedures and deprecated ones (neo4j-contrib/neo4j-apoc-procedures#3325) * [gRNAet7B] added trigger new procs documentation * changes review - procedure description * changed listener wording * added system db note * var. small changes * [gRNAet7B] Fixes triggers (neo4j-contrib/neo4j-apoc-procedures#3369) * [coZSswV2] Fix typo in triggers error message * [coZSswV2] Assert new triggers can't add TransactionEventListeners to "system" * [coZSswV2] Assert old triggers can't add TransactionEventListeners to "system" * [gRNAet7B] removed unused import * [gRNAet7B] moved TriggerInfo class, removed wrong extended file * [gRNAet7B] Add @Admin to trigger procedures (neo4j-contrib/neo4j-apoc-procedures#3357) * [qwJFy8pp] Add @Admin to trigger procedures * added admin in trigger.list and docs note * changed admin doc * [gRNAet7B] moved classes - changed TriggerInfo - err. handling changes * [gRNAet7B] Cleanup trigger docs (neo4j-contrib/neo4j-apoc-procedures#3378) * [gRNAet7B] added TriggerEnterpriseFeaturesTest, removed log and session db check * [gRNAet7B] changed descriptions consistently with to Trigger.java 5.x ones Co-authored-by: Nacho Cordón <[email protected]> Co-authored-by: Daniel Leaver <[email protected]>
- Loading branch information
1 parent
95121ff
commit c575792
Showing
15 changed files
with
1,497 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletions
148
core/src/main/java/apoc/trigger/TriggerHandlerNewProcedures.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
package apoc.trigger; | ||
|
||
import apoc.SystemLabels; | ||
import apoc.SystemPropertyKeys; | ||
import apoc.util.Util; | ||
import org.apache.commons.lang3.tuple.Pair; | ||
import org.neo4j.graphdb.Node; | ||
import org.neo4j.graphdb.ResourceIterator; | ||
import org.neo4j.graphdb.Transaction; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
import java.util.function.Consumer; | ||
import java.util.stream.Stream; | ||
|
||
import static apoc.ApocConfig.APOC_TRIGGER_ENABLED; | ||
import static apoc.ApocConfig.apocConfig; | ||
import static apoc.trigger.TriggerInfo.fromNode; | ||
|
||
public class TriggerHandlerNewProcedures { | ||
public static final String NOT_ENABLED_ERROR = "Triggers have not been enabled." + | ||
" Set 'apoc.trigger.enabled=true' in your apoc.conf file located in the $NEO4J_HOME/conf/ directory."; | ||
|
||
|
||
private static boolean isEnabled() { | ||
return apocConfig().getBoolean(APOC_TRIGGER_ENABLED); | ||
} | ||
|
||
public static void checkEnabled() { | ||
if (!isEnabled()) { | ||
throw new RuntimeException(NOT_ENABLED_ERROR); | ||
} | ||
} | ||
|
||
public static TriggerInfo install(String databaseName, String triggerName, String statement, Map<String,Object> selector, Map<String,Object> params) { | ||
AtomicReference<TriggerInfo> previous = new AtomicReference<>(); | ||
|
||
withSystemDb(tx -> { | ||
Node node = Util.mergeNode(tx, SystemLabels.ApocTrigger, null, | ||
Pair.of(SystemPropertyKeys.database.name(), databaseName), | ||
Pair.of(SystemPropertyKeys.name.name(), triggerName)); | ||
|
||
// we'll return previous trigger info | ||
previous.set( fromNode(node, true) ); | ||
|
||
node.setProperty(SystemPropertyKeys.statement.name(), statement); | ||
node.setProperty(SystemPropertyKeys.selector.name(), Util.toJson(selector)); | ||
node.setProperty(SystemPropertyKeys.params.name(), Util.toJson(params)); | ||
node.setProperty(SystemPropertyKeys.paused.name(), false); | ||
|
||
setLastUpdate(databaseName, tx); | ||
}); | ||
|
||
return previous.get(); | ||
} | ||
|
||
public static TriggerInfo drop(String databaseName, String triggerName) { | ||
AtomicReference<TriggerInfo> previous = new AtomicReference<>(); | ||
|
||
withSystemDb(tx -> { | ||
getTriggerNodes(databaseName, tx, triggerName) | ||
.forEachRemaining(node -> { | ||
previous.set( fromNode(node, false) ); | ||
node.delete(); | ||
}); | ||
|
||
setLastUpdate(databaseName, tx); | ||
}); | ||
|
||
return previous.get(); | ||
} | ||
|
||
public static TriggerInfo updatePaused(String databaseName, String name, boolean paused) { | ||
AtomicReference<TriggerInfo> result = new AtomicReference<>(); | ||
|
||
withSystemDb(tx -> { | ||
getTriggerNodes(databaseName, tx, name) | ||
.forEachRemaining(node -> { | ||
node.setProperty( SystemPropertyKeys.paused.name(), paused ); | ||
|
||
// we'll return previous trigger info | ||
result.set( fromNode(node, true) ); | ||
}); | ||
|
||
setLastUpdate(databaseName, tx); | ||
}); | ||
|
||
return result.get(); | ||
} | ||
|
||
public static List<TriggerInfo> dropAll(String databaseName) { | ||
final List<TriggerInfo> previous = new ArrayList<>(); | ||
|
||
withSystemDb(tx -> { | ||
getTriggerNodes(databaseName, tx) | ||
.forEachRemaining(node -> { | ||
String triggerName = (String) node.getProperty(SystemPropertyKeys.name.name()); | ||
|
||
// we'll return previous trigger info | ||
previous.add( fromNode(node, false) ); | ||
node.delete(); | ||
}); | ||
setLastUpdate(databaseName, tx); | ||
}); | ||
|
||
return previous; | ||
} | ||
|
||
public static Stream<TriggerInfo> getTriggerNodesList(String databaseName, Transaction tx) { | ||
return getTriggerNodes(databaseName, tx) | ||
.stream() | ||
.map(trigger -> TriggerInfo.fromNode(trigger, true)); | ||
} | ||
|
||
public static ResourceIterator<Node> getTriggerNodes(String databaseName, Transaction tx) { | ||
return getTriggerNodes(databaseName, tx, null); | ||
} | ||
|
||
public static ResourceIterator<Node> getTriggerNodes(String databaseName, Transaction tx, String name) { | ||
final SystemLabels label = SystemLabels.ApocTrigger; | ||
final String dbNameKey = SystemPropertyKeys.database.name(); | ||
if (name == null) { | ||
return tx.findNodes(label, dbNameKey, databaseName); | ||
} | ||
return tx.findNodes(label, dbNameKey, databaseName, | ||
SystemPropertyKeys.name.name(), name); | ||
} | ||
|
||
public static void withSystemDb(Consumer<Transaction> consumer) { | ||
try (Transaction tx = apocConfig().getSystemDb().beginTx()) { | ||
consumer.accept(tx); | ||
tx.commit(); | ||
} | ||
} | ||
|
||
private static void setLastUpdate(String databaseName, Transaction tx) { | ||
Node node = tx.findNode(SystemLabels.ApocTriggerMeta, SystemPropertyKeys.database.name(), databaseName); | ||
if (node == null) { | ||
node = tx.createNode(SystemLabels.ApocTriggerMeta); | ||
node.setProperty(SystemPropertyKeys.database.name(), databaseName); | ||
} | ||
final long value = System.currentTimeMillis(); | ||
node.setProperty(SystemPropertyKeys.lastUpdated.name(), value); | ||
} | ||
|
||
} |
Oops, something went wrong.