예제 #1
0
  @Test
  public void shouldBeAbleToAccessExceptionThrownInEventHook() {
    class MyFancyException extends Exception {}

    ExceptionThrowingEventHandler handler =
        new ExceptionThrowingEventHandler(new MyFancyException(), null, null);
    GraphDatabaseService db = dbRule.getGraphDatabaseService();
    db.registerTransactionEventHandler(handler);

    try {
      Transaction tx = db.beginTx();
      try {
        db.createNode().delete();
        tx.success();
        tx.close();
        fail("Should fail commit");
      } catch (TransactionFailureException e) {
        Throwable currentEx = e;
        do {
          currentEx = currentEx.getCause();
          if (currentEx instanceof MyFancyException) {
            return;
          }
        } while (currentEx.getCause() != null);
        fail(
            "Expected to find the exception thrown in the event hook as the cause of transaction failure.");
      }
    } finally {
      db.unregisterTransactionEventHandler(handler);
    }
  }
  @Test
  public void shouldAccessAssignedLabels() throws Exception {
    // given
    GraphDatabaseService db = dbRule.getGraphDatabaseService();

    ChangedLabels labels = (ChangedLabels) db.registerTransactionEventHandler(new ChangedLabels());
    try {
      // when
      try (Transaction tx = db.beginTx()) {
        Node node1 = db.createNode(), node2 = db.createNode(), node3 = db.createNode();

        labels.add(node1, "Foo");
        labels.add(node2, "Bar");
        labels.add(node3, "Baz");
        labels.add(node3, "Bar");

        labels.activate();
        tx.success();
      }
      // then
      assertTrue(labels.isEmpty());
    } finally {
      db.unregisterTransactionEventHandler(labels);
    }
  }
예제 #3
0
  @Test
  public void testRegisterUnregisterHandlers() {
    Object value1 = 10;
    Object value2 = 3.5D;
    DummyTransactionEventHandler<Integer> handler1 =
        new DummyTransactionEventHandler<>((Integer) value1);
    DummyTransactionEventHandler<Double> handler2 =
        new DummyTransactionEventHandler<>((Double) value2);

    GraphDatabaseService db = dbRule.getGraphDatabaseService();
    try {
      db.unregisterTransactionEventHandler(handler1);
      fail("Shouldn't be able to do unregister on a unregistered handler");
    } catch (IllegalStateException e) {
      /* Good */
    }

    assertTrue(handler1 == db.registerTransactionEventHandler(handler1));
    assertTrue(handler1 == db.registerTransactionEventHandler(handler1));
    assertTrue(handler1 == db.unregisterTransactionEventHandler(handler1));

    try {
      db.unregisterTransactionEventHandler(handler1);
      fail("Shouldn't be able to do unregister on a unregistered handler");
    } catch (IllegalStateException e) {
      /* Good */
    }

    assertTrue(handler1 == db.registerTransactionEventHandler(handler1));
    assertTrue(handler2 == db.registerTransactionEventHandler(handler2));
    assertTrue(handler1 == db.unregisterTransactionEventHandler(handler1));
    assertTrue(handler2 == db.unregisterTransactionEventHandler(handler2));

    db.registerTransactionEventHandler(handler1);
    try (Transaction tx = db.beginTx()) {
      db.createNode().delete();
      tx.success();
    }

    assertNotNull(handler1.beforeCommit);
    assertNotNull(handler1.afterCommit);
    assertNull(handler1.afterRollback);
    assertEquals(value1, handler1.receivedState);
    assertNotNull(handler1.receivedTransactionData);
    db.unregisterTransactionEventHandler(handler1);
  }
예제 #4
0
  @Test
  public void makeSureBeforeAfterAreCalledCorrectly() {
    List<TransactionEventHandler<Object>> handlers = new ArrayList<>();
    handlers.add(new FailingEventHandler<>(new DummyTransactionEventHandler<>(null), false));
    handlers.add(new FailingEventHandler<>(new DummyTransactionEventHandler<>(null), false));
    handlers.add(new FailingEventHandler<>(new DummyTransactionEventHandler<>(null), true));
    handlers.add(new FailingEventHandler<>(new DummyTransactionEventHandler<>(null), false));
    GraphDatabaseService db = dbRule.getGraphDatabaseService();
    for (TransactionEventHandler<Object> handler : handlers) {
      db.registerTransactionEventHandler(handler);
    }

    try {
      Transaction tx = db.beginTx();
      try {
        db.createNode().delete();
        tx.success();
        tx.close();
        fail("Should fail commit");
      } catch (TransactionFailureException e) { // OK
      }
      verifyHandlerCalls(handlers, false);

      db.unregisterTransactionEventHandler(handlers.remove(2));
      for (TransactionEventHandler<Object> handler : handlers) {
        ((DummyTransactionEventHandler<Object>) ((FailingEventHandler<Object>) handler).source)
            .reset();
      }
      try (Transaction transaction = db.beginTx()) {
        db.createNode().delete();
        transaction.success();
      }
      verifyHandlerCalls(handlers, true);
    } finally {
      for (TransactionEventHandler<Object> handler : handlers) {
        db.unregisterTransactionEventHandler(handler);
      }
    }
  }
예제 #5
0
 @Test
 public void makeSureHandlerIsntCalledWhenTxRolledBack() {
   DummyTransactionEventHandler<Integer> handler = new DummyTransactionEventHandler<Integer>(10);
   GraphDatabaseService db = dbRule.getGraphDatabaseService();
   db.registerTransactionEventHandler(handler);
   try {
     try (Transaction tx = db.beginTx()) {
       db.createNode().delete();
     }
     assertNull(handler.beforeCommit);
     assertNull(handler.afterCommit);
     assertNull(handler.afterRollback);
   } finally {
     db.unregisterTransactionEventHandler(handler);
   }
 }
예제 #6
0
  @Test
  public void makeSureHandlersCantBeRegisteredTwice() {
    DummyTransactionEventHandler<Object> handler = new DummyTransactionEventHandler<>(null);
    GraphDatabaseService db = dbRule.getGraphDatabaseService();
    db.registerTransactionEventHandler(handler);
    db.registerTransactionEventHandler(handler);
    try (Transaction tx = db.beginTx()) {
      db.createNode().delete();
      tx.success();
    }
    assertEquals(Integer.valueOf(0), handler.beforeCommit);
    assertEquals(Integer.valueOf(1), handler.afterCommit);
    assertNull(handler.afterRollback);

    db.unregisterTransactionEventHandler(handler);
  }
예제 #7
0
  @Test
  public void modifiedPropertyCanByFurtherModifiedInBeforeCommit() throws Exception {
    // Given
    // -- create node and set property on it in one transaction
    GraphDatabaseService db = dbRule.getGraphDatabaseService();
    final String key = "key";
    final Object value1 = "the old value";
    final Object value2 = "the new value";
    final Node node;
    try (Transaction tx = db.beginTx()) {
      node = db.createNode();
      node.setProperty(key, "initial value");
      tx.success();
    }
    // -- register a tx handler which will override a property
    TransactionEventHandler<Void> handler =
        new TransactionEventHandler.Adapter<Void>() {
          @Override
          public Void beforeCommit(TransactionData data) throws Exception {
            Node modifiedNode = data.assignedNodeProperties().iterator().next().entity();
            assertEquals(node, modifiedNode);
            modifiedNode.setProperty(key, value2);
            return null;
          }
        };
    db.registerTransactionEventHandler(handler);

    try (Transaction tx = db.beginTx()) {
      // When
      node.setProperty(key, value1);
      tx.success();
    }
    // Then
    assertThat(node, inTx(db, hasProperty(key).withValue(value2)));
    db.unregisterTransactionEventHandler(handler);
  }
예제 #8
0
  @Test
  public void shouldGetCorrectTransactionDataUponCommit() {
    // Create new data, nothing modified, just added/created
    ExpectedTransactionData expectedData = new ExpectedTransactionData();
    VerifyingTransactionEventHandler handler = new VerifyingTransactionEventHandler(expectedData);
    GraphDatabaseService db = dbRule.getGraphDatabaseService();
    db.registerTransactionEventHandler(handler);
    Node node1 = null, node2, node3 = null;
    Relationship rel1 = null, rel2 = null;
    try {
      try (Transaction tx = db.beginTx()) {
        node1 = db.createNode();
        expectedData.expectedCreatedNodes.add(node1);

        node2 = db.createNode();
        expectedData.expectedCreatedNodes.add(node2);

        rel1 = node1.createRelationshipTo(node2, RelTypes.TXEVENT);
        expectedData.expectedCreatedRelationships.add(rel1);

        node1.setProperty("name", "Mattias");
        expectedData.assignedProperty(node1, "name", "Mattias", null);

        node1.setProperty("last name", "Persson");
        expectedData.assignedProperty(node1, "last name", "Persson", null);

        node1.setProperty("counter", 10);
        expectedData.assignedProperty(node1, "counter", 10, null);

        rel1.setProperty("description", "A description");
        expectedData.assignedProperty(rel1, "description", "A description", null);

        rel1.setProperty("number", 4.5D);
        expectedData.assignedProperty(rel1, "number", 4.5D, null);

        node3 = db.createNode();
        expectedData.expectedCreatedNodes.add(node3);
        rel2 = node3.createRelationshipTo(node2, RelTypes.TXEVENT);
        expectedData.expectedCreatedRelationships.add(rel2);

        node3.setProperty("name", "Node 3");
        expectedData.assignedProperty(node3, "name", "Node 3", null);
        tx.success();
      }

      assertTrue("Should have been invoked", handler.hasBeenCalled());
      if (handler.failure() != null) {
        throw new RuntimeException(handler.failure());
      }
    } finally {
      db.unregisterTransactionEventHandler(handler);
    }

    // Use the above data and modify it, change properties, delete stuff
    expectedData = new ExpectedTransactionData();
    handler = new VerifyingTransactionEventHandler(expectedData);
    db.registerTransactionEventHandler(handler);
    try {
      try (Transaction tx = db.beginTx()) {
        Node newNode = db.createNode();
        expectedData.expectedCreatedNodes.add(newNode);

        Node tempNode = db.createNode();
        Relationship tempRel = tempNode.createRelationshipTo(node1, RelTypes.TXEVENT);
        tempNode.setProperty("something", "Some value");
        tempRel.setProperty("someproperty", 101010);
        tempNode.removeProperty("nothing");

        node3.setProperty("test", "hello");
        node3.setProperty("name", "No name");
        node3.delete();
        expectedData.expectedDeletedNodes.add(node3);
        expectedData.removedProperty(node3, "name", null, "Node 3");

        node1.setProperty("new name", "A name");
        node1.setProperty("new name", "A better name");
        expectedData.assignedProperty(node1, "new name", "A better name", null);
        node1.setProperty("name", "Nothing");
        node1.setProperty("name", "Mattias Persson");
        expectedData.assignedProperty(node1, "name", "Mattias Persson", "Mattias");
        node1.removeProperty("counter");
        expectedData.removedProperty(node1, "counter", null, 10);
        node1.removeProperty("last name");
        node1.setProperty("last name", "Hi");
        expectedData.assignedProperty(node1, "last name", "Hi", "Persson");

        rel2.delete();
        expectedData.expectedDeletedRelationships.add(rel2);

        rel1.removeProperty("number");
        expectedData.removedProperty(rel1, "number", null, 4.5D);
        rel1.setProperty("description", "Ignored");
        rel1.setProperty("description", "New");
        expectedData.assignedProperty(rel1, "description", "New", "A description");

        tempRel.delete();
        tempNode.delete();
        tx.success();
      }

      assertTrue("Should have been invoked", handler.hasBeenCalled());
      if (handler.failure() != null) {
        throw new RuntimeException(handler.failure());
      }
    } finally {
      db.unregisterTransactionEventHandler(handler);
    }
  }
  @Test
  public void shouldAccessRelationshipDataInAfterCommit() throws Exception {
    // GIVEN
    final GraphDatabaseService db = dbRule.getGraphDatabaseService();
    final AtomicInteger accessCount = new AtomicInteger();
    final Map<Long, Triplet<Node, String, Node>> expectedRelationshipData = new HashMap<>();
    TransactionEventHandler<Void> handler =
        new TransactionEventHandler.Adapter<Void>() {
          @Override
          public void afterCommit(TransactionData data, Void state) {
            accessCount.set(0);
            try (Transaction tx = db.beginTx()) {
              for (Relationship relationship : data.createdRelationships()) {
                accessData(relationship);
              }
              for (PropertyEntry<Relationship> change : data.assignedRelationshipProperties()) {
                accessData(change.entity());
              }
              for (PropertyEntry<Relationship> change : data.removedRelationshipProperties()) {
                accessData(change.entity());
              }
              tx.success();
            }
          }

          private void accessData(Relationship relationship) {
            accessCount.incrementAndGet();
            Triplet<Node, String, Node> expectancy =
                expectedRelationshipData.get(relationship.getId());
            assertNotNull(expectancy);
            assertEquals(expectancy.first(), relationship.getStartNode());
            assertEquals(expectancy.second(), relationship.getType().name());
            assertEquals(expectancy.third(), relationship.getEndNode());
          }
        };
    db.registerTransactionEventHandler(handler);

    // WHEN
    try {
      Relationship relationship;
      try (Transaction tx = db.beginTx()) {
        relationship = db.createNode().createRelationshipTo(db.createNode(), MyRelTypes.TEST);
        expectedRelationshipData.put(
            relationship.getId(),
            Triplet.of(
                relationship.getStartNode(),
                relationship.getType().name(),
                relationship.getEndNode()));
        tx.success();
      }
      // THEN
      assertEquals(1, accessCount.get());

      // and WHEN
      try (Transaction tx = db.beginTx()) {
        relationship.setProperty("name", "Smith");
        Relationship otherRelationship =
            db.createNode().createRelationshipTo(db.createNode(), MyRelTypes.TEST2);
        expectedRelationshipData.put(
            otherRelationship.getId(),
            Triplet.of(
                otherRelationship.getStartNode(),
                otherRelationship.getType().name(),
                otherRelationship.getEndNode()));
        tx.success();
      }
      // THEN
      assertEquals(2, accessCount.get());

      // and WHEN
      try (Transaction tx = db.beginTx()) {
        relationship.delete();
        tx.success();
      }
      // THEN
      assertEquals(1, accessCount.get());
    } finally {
      db.unregisterTransactionEventHandler(handler);
    }
  }