Hello,
I’m trying to write integration test for our software, where in various scenarios we expect a certain set of events to be stored in the eventstore.
In the @Before method of our test, I want to clean up a stream an write certain events to that stream.
I’m having problems with the first part: the clean up of the stream. Based upon what I found here, I trying to use the ‘Truncate Before’ by setting the $tb to the stream metadata.
In order to determine the number for the $tb-value I read the feed of /stream/my-stream and us the number of the first entry (So far I’m fine)
In order to set the $tb I POST to the POST /streams/my-stream/metadata the following message:
[{“eventType”:“TruncateBeforeFromIntegrationTest”,“eventId”:“898534db-b423-49ee-b98d-e03147861355”,“data”:{"$tb":3}}]
and I get “HTTP/1.1 201 Created” with /streams/%24%24my-stream//11"
When I get /streams/my-stream/metadata I see: No 11 / Stream: $$my-stream with correct type and timestamp and as data:
{
"$tb": 3
}
But when I get /streams/my-stream I still see the list of 4 previous events in the stream.
What more do I need to do or what do I need to change to stop seeing the previous events?
With kind regards,
Marco Beelen
also what version are you running?
Greg (and all others),
First of all I was running the stable 2.0.1 version, in which the $tb isn’t supported at all, so I upgraded to the v3.0.0rc2.
I was trying to write to the metadata stream using the Eventstore.JVM.
Finally I managed to write the metadata properly so that the Eventstore considers a stream to be ‘empty’ again in a Integration Test.
So the problem is solved already. The code which solved the problem for us is appended below.
Cheers,
Marco Beelen
public void truncateBefore(String streamName, Long eventNumber) {
final ActorSystem system = ActorSystem.create();
final Settings settings = new SettingsBuilder()
.address(new InetSocketAddress(config.getIpAddress(), config.getBinaryPort()))
.defaultCredentials(config.getLoginName(), config.getLoginPassword())
.build();
final ActorRef connection = system.actorOf(ConnectionActor.getProps(settings));
final ActorRef writeResult = system.actorOf(Props.create(WriteResult.class));
String jsonPayload = "{\"$tb\": " + eventNumber + "}";
final EventData event = new EventDataBuilder("$metadata")
.eventId(UUID.randomUUID())
.jsonData(jsonPayload)
.build();
final WriteEvents writeEvents = new WriteEventsBuilder("$$" + streamName)
.addEvent(event)
.expectAnyVersion()
.build();
connection.tell(writeEvents, writeResult);
}
public static class WriteResult extends UntypedActor {
public void onReceive(Object message) throws Exception {
if (message instanceof Status.Failure) {
final Status.Failure failure = ((Status.Failure) message);
System.err.println("Writing to EventStream failed, due to" + failure.cause().getMessage());
throw (EsException) failure.cause();
} else if (message instanceof WriteEventsCompleted) {
final WriteEventsCompleted completed = (WriteEventsCompleted) message;
final EventNumber.Exact eventNumber = completed.firstEventNumber();
System.out.println("eventNumber: " + eventNumber);
}
}
}
If you use delete without hard delete it will do this for you internally
And how would we have to send such a delete command to a stream (or it’s metadata)?
_connection.Delete … or over http a delete.
public Task DeleteStreamAsync(string stream, int expectedVersion, UserCredentials userCredentials = null)
public Task DeleteStreamAsync(string stream, int expectedVersion, bool hardDelete, UserCredentials userCredentials = null)
By default it will truncate unless you specify hard delete
Over http there is a header for harddelete:
https://github.com/eventstore/eventstore/wiki/Deleting-a-Stream-%28HTTP%29
Greg
Hi Marko,
To delete stream in v3xx or 2xx (example in Scala)
https://github.com/EventStore/EventStore.JVM/blob/master/src/test/scala/eventstore/DeleteStreamITest.scala#L41
Btw when JVM client released against EventStore 3.0.0 it will have have method WriteEventsBuilder.streamMetadata with some helpers