Skip to content

Commit

Permalink
eventuate-clients#9: Enhancing the Eventuate Java Client According GD…
Browse files Browse the repository at this point in the history
…PR. Adding tests.
  • Loading branch information
dartartem committed Apr 18, 2018
1 parent 21b373c commit b54df70
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.eventuate.*;
import io.eventuate.encryption.EncryptedEventData;
import io.eventuate.encryption.EventDataEncryptor;
import io.eventuate.encryption.NoEncryptionKeyProvidedException;
import io.eventuate.javaclient.commonimpl.schemametadata.EmptyEventSchemaMetadataManager;
import io.eventuate.javaclient.commonimpl.schemametadata.EventSchemaMetadataManager;

Expand Down Expand Up @@ -124,8 +125,15 @@ public <T extends Aggregate<T>> CompletableFuture<EntityWithMetadata<T>> find(Cl
.map(event ->
AggregateCrudMapping.toEventWithMetadata(event, json -> findOptions
.flatMap(FindOptions::getEncryptionKey)
.map(k -> EncryptedEventData.isEventDataStringEncrypted(json) ? eventDataEncryptor.decrypt(k, json) : json)
.orElse(json)))
.map(k -> EncryptedEventData.isEventDataStringEncrypted(json) ?
eventDataEncryptor.decrypt(k, EncryptedEventData.fromEventDataString(json).getData()) :
json)
.orElseGet(() -> {
if (EncryptedEventData.isEventDataStringEncrypted(json)) {
throw new NoEncryptionKeyProvidedException(EncryptedEventData.fromEventDataString(json));
}
return json;
})))
.collect(Collectors.toList());

List<Event> events = eventsWithIds.stream().map(EventWithMetadata::getEvent).collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import io.eventuate.SubscriberOptions;
import io.eventuate.UpdateOptions;
import io.eventuate.encryption.EncryptedEventData;
import io.eventuate.encryption.NoEncryptionKeyProvidedException;
import io.eventuate.javaclient.commonimpl.*;
import io.eventuate.encryption.EventDataEncryptor;
import io.eventuate.sync.EventuateAggregateStore;
Expand Down Expand Up @@ -107,10 +108,18 @@ public <T extends Aggregate<T>> EntityWithMetadata<T> find(Class<T> clasz, Strin
.getEvents()
.stream()
.map(event ->
AggregateCrudMapping.toEventWithMetadata(event, json -> findOptions
.flatMap(FindOptions::getEncryptionKey)
.map(k -> EncryptedEventData.isEventDataStringEncrypted(json) ? eventDataEncryptor.decrypt(k, json) : json)
.orElse(json)))
AggregateCrudMapping.toEventWithMetadata(event, json ->
findOptions
.flatMap(FindOptions::getEncryptionKey)
.map(k -> EncryptedEventData.isEventDataStringEncrypted(json) ?
eventDataEncryptor.decrypt(k, EncryptedEventData.fromEventDataString(json).getData()) :
json)
.orElseGet(() -> {
if (EncryptedEventData.isEventDataStringEncrypted(json)) {
throw new NoEncryptionKeyProvidedException(EncryptedEventData.fromEventDataString(json));
}
return json;
})))
.collect(Collectors.toList());
List<Event> events = eventsWithIds.stream().map(EventWithMetadata::getEvent).collect(Collectors.toList());
return new EntityWithMetadata<T>(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package io.eventuate.javaclient.spring.autoconfiguration;

import io.eventuate.*;
import io.eventuate.encryption.EncryptionKey;
import io.eventuate.encryption.EventDataEncryptor;
import io.eventuate.encryption.NoEncryptionKeyProvidedException;
import io.vertx.core.json.Json;
import org.junit.Assert;
import org.junit.Test;

public abstract class AbstractEventuateAggregateStoreEncryptionTest {

private static String hexRegExp = "^[0-9a-fA-F]+$";

private static final String idKey = "1";
private static final String key = "Super strong password";
private static final String salt = "47b4033642e911e8842f0ed5f89f718b";

private static final String testEventData = "Some secret data";
private static final String testEventDataUpdated = "Some secret data (Updated)";

protected static final EncryptionKey encryptionKey = new EncryptionKey(idKey, key, salt);

protected static final EventDataEncryptor eventDataEncryptor = new EventDataEncryptor();

@Test
public void testSaveEncrypted() throws Exception {
EntityIdAndVersion entityIdAndVersion = save(testEventData);

NoEncryptionKeyProvidedException noEncryptionKeyProvidedException = null;

try {
find(entityIdAndVersion, false);
} catch (NoEncryptionKeyProvidedException e) {
noEncryptionKeyProvidedException = e;
}

Assert.assertNotNull(noEncryptionKeyProvidedException);

String data = noEncryptionKeyProvidedException.getEncryptedEventData().getData();

Assert.assertNotNull(data);
Assert.assertFalse(data.trim().isEmpty());
Assert.assertTrue(data.matches(hexRegExp));
Assert.assertEquals(Json.encode(new SomeEvent(testEventData)), eventDataEncryptor.decrypt(encryptionKey, data));

Assert.assertFalse(testEventData.matches(hexRegExp));
}

@Test
public void testSaveAndFind() throws Exception {
EntityIdAndVersion entityIdAndVersion = save(testEventData);

EntityWithMetadata<SomeAggregate> entityEntityWithMetadata = find(entityIdAndVersion, true);

Assert.assertEquals(1, entityEntityWithMetadata.getEvents().size());
Assert.assertEquals(testEventData, ((SomeEvent)entityEntityWithMetadata.getEvents().get(0).getEvent()).getData());
}

@Test
public void testUpdateAndFind() throws Exception {
EntityIdAndVersion entityIdAndVersion = save(testEventData);

entityIdAndVersion = update(entityIdAndVersion, testEventDataUpdated);

EntityWithMetadata<SomeAggregate> entityEntityWithMetadata = find(entityIdAndVersion, true);

Assert.assertEquals(2, entityEntityWithMetadata.getEvents().size());
Assert.assertEquals(testEventDataUpdated,
((SomeEvent)entityEntityWithMetadata.getEvents().get(1).getEvent()).getData());
}

protected abstract EntityIdAndVersion save(String data) throws Exception;
protected abstract EntityIdAndVersion update(EntityIdAndVersion entityIdAndVersion, String data) throws Exception;
protected abstract EntityWithMetadata<SomeAggregate> find(EntityIdAndVersion entityIdAndVersion, boolean encrypted) throws Exception;

public static class SomeAggregate implements Aggregate<SomeAggregate> {
@Override
public SomeAggregate applyEvent(Event event) {
return this;
}
}

public static class SomeEvent implements Event {
private String data;

public SomeEvent() {
}

public SomeEvent(String data) {
this.data = data;
}

public String getData() {
return data;
}

public void setData(String data) {
this.data = data;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.eventuate.javaclient.spring.autoconfiguration;

import io.eventuate.*;
import io.eventuate.encryption.NoEncryptionKeyProvidedException;
import io.eventuate.javaclient.saasclient.EventuateAggregateStoreBuilder;
import org.junit.Assert;
import org.junit.runner.RunWith;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Collections;
import java.util.Optional;
import java.util.concurrent.ExecutionException;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = AutoConfigurationIntegrationTestConfiguration.class)
@IntegrationTest
public class EventuateAggregateStoreEncryptionTest extends AbstractEventuateAggregateStoreEncryptionTest {

private io.eventuate.EventuateAggregateStore aggregateStore = EventuateAggregateStoreBuilder.defaultFromEnv();

@Override
protected EntityIdAndVersion save(String data) throws Exception {
return aggregateStore.save(SomeAggregate.class,
Collections.singletonList(new SomeEvent(data)),
new SaveOptions().withEncryptionKey(encryptionKey)).get();
}

@Override
protected EntityIdAndVersion update(EntityIdAndVersion entityIdAndVersion, String data) throws Exception {
return aggregateStore.update(SomeAggregate.class,
entityIdAndVersion,
Collections.singletonList(new SomeEvent(data)),
new UpdateOptions().withEncryptionKey(encryptionKey)).get();
}

@Override
protected EntityWithMetadata<SomeAggregate> find(EntityIdAndVersion entityIdAndVersion,
boolean encrypted) throws Exception {
try {
return aggregateStore.find(SomeAggregate.class,
entityIdAndVersion.getEntityId(),
encrypted ? Optional.of(new FindOptions().withEncryptionKey(encryptionKey)) : Optional.empty()).get();
} catch (ExecutionException e) {
Assert.assertTrue(e.getCause() instanceof NoEncryptionKeyProvidedException);
throw (NoEncryptionKeyProvidedException) e.getCause();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.eventuate.javaclient.spring.autoconfiguration;

import io.eventuate.*;
import io.eventuate.javaclient.saasclient.EventuateAggregateStoreBuilder;
import io.eventuate.sync.EventuateAggregateStore;
import org.junit.runner.RunWith;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Collections;
import java.util.Optional;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = AutoConfigurationIntegrationTestConfiguration.class)
@IntegrationTest
public class SyncEventuateAggregateStoreEncryptionTest extends AbstractEventuateAggregateStoreEncryptionTest {

private EventuateAggregateStore aggregateStore = EventuateAggregateStoreBuilder.standard().buildSync();

@Override
protected EntityIdAndVersion save(String data) {
return aggregateStore.save(SomeAggregate.class,
Collections.singletonList(new SomeEvent(data)),
new SaveOptions().withEncryptionKey(encryptionKey));
}

@Override
protected EntityIdAndVersion update(EntityIdAndVersion entityIdAndVersion, String data) {
return aggregateStore.update(SomeAggregate.class,
entityIdAndVersion,
Collections.singletonList(new SomeEvent(data)),
new UpdateOptions().withEncryptionKey(encryptionKey));
}

@Override
protected EntityWithMetadata<SomeAggregate> find(EntityIdAndVersion entityIdAndVersion, boolean encrypted) {
return aggregateStore.find(SomeAggregate.class,
entityIdAndVersion.getEntityId(),
encrypted ? Optional.of(new FindOptions().withEncryptionKey(encryptionKey)) : Optional.empty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ public UpdateOptions withTriggeringEvent(EventContext eventContext) {
return new UpdateOptions(Optional.ofNullable(eventContext), this.eventMetadata, this.snapshot, this.interceptor);
}

public UpdateOptions withEncryptionKey(EncryptionKey encryptionKey) {
return new UpdateOptions(this.triggeringEvent, this.eventMetadata, this.snapshot, this.interceptor, Optional.of(encryptionKey));
}

public UpdateOptions withEventMetadata(Map<String, String> eventMetadata) {
return new UpdateOptions(this.triggeringEvent, Optional.of(eventMetadata), this.snapshot, this.interceptor);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.eventuate.encryption;

public class NoEncryptionKeyProvidedException extends RuntimeException {
private EncryptedEventData encryptedEventData;

public NoEncryptionKeyProvidedException(EncryptedEventData encryptedEventData) {
this.encryptedEventData = encryptedEventData;
}

public EncryptedEventData getEncryptedEventData() {
return encryptedEventData;
}
}

0 comments on commit b54df70

Please sign in to comment.