From 18d944f2287b133da8a7618e76be672bff6daaca Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 23 Feb 2018 10:13:57 +1300 Subject: [PATCH] Test only - copy/add multi-tenant partition tests --- .../multitenant/partition/CurrentTenant.java | 14 ++++ .../multitenant/partition/MtBaseDomain.java | 57 +++++++++++++ .../org/multitenant/partition/MtContent.java | 32 ++++++++ .../org/multitenant/partition/MtTenant.java | 67 ++++++++++++++++ .../multitenant/partition/MtTenantAware.java | 22 +++++ .../partition/MultiTenantPartitionTest.java | 80 +++++++++++++++++++ .../multitenant/partition/UserContext.java | 46 +++++++++++ 7 files changed, 318 insertions(+) create mode 100644 src/test/java/org/multitenant/partition/CurrentTenant.java create mode 100644 src/test/java/org/multitenant/partition/MtBaseDomain.java create mode 100644 src/test/java/org/multitenant/partition/MtContent.java create mode 100644 src/test/java/org/multitenant/partition/MtTenant.java create mode 100644 src/test/java/org/multitenant/partition/MtTenantAware.java create mode 100644 src/test/java/org/multitenant/partition/MultiTenantPartitionTest.java create mode 100644 src/test/java/org/multitenant/partition/UserContext.java diff --git a/src/test/java/org/multitenant/partition/CurrentTenant.java b/src/test/java/org/multitenant/partition/CurrentTenant.java new file mode 100644 index 000000000..7e8b73b9f --- /dev/null +++ b/src/test/java/org/multitenant/partition/CurrentTenant.java @@ -0,0 +1,14 @@ +package org.multitenant.partition; + +import io.ebean.config.CurrentTenantProvider; + +class CurrentTenant implements CurrentTenantProvider { + + /** + * Return the current tenantId from the user context. + */ + @Override + public String currentId() { + return UserContext.get().getTenantId(); + } +} diff --git a/src/test/java/org/multitenant/partition/MtBaseDomain.java b/src/test/java/org/multitenant/partition/MtBaseDomain.java new file mode 100644 index 000000000..41a23d20f --- /dev/null +++ b/src/test/java/org/multitenant/partition/MtBaseDomain.java @@ -0,0 +1,57 @@ +package org.multitenant.partition; + +import io.ebean.annotation.WhenCreated; +import io.ebean.annotation.WhenModified; + +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import javax.persistence.Version; +import java.time.Instant; + +@MappedSuperclass +public abstract class MtBaseDomain { + + @Id + long id; + + @WhenModified + Instant whenModified; + + @WhenCreated + Instant whenCreated; + + @Version + long version; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Instant getWhenModified() { + return whenModified; + } + + public void setWhenModified(Instant whenModified) { + this.whenModified = whenModified; + } + + public Instant getWhenCreated() { + return whenCreated; + } + + public void setWhenCreated(Instant whenCreated) { + this.whenCreated = whenCreated; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } +} diff --git a/src/test/java/org/multitenant/partition/MtContent.java b/src/test/java/org/multitenant/partition/MtContent.java new file mode 100644 index 000000000..9489c1342 --- /dev/null +++ b/src/test/java/org/multitenant/partition/MtContent.java @@ -0,0 +1,32 @@ +package org.multitenant.partition; + +import javax.persistence.Entity; + +@Entity +public class MtContent extends MtTenantAware { + + String title; + + String body; + + public MtContent(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + +} diff --git a/src/test/java/org/multitenant/partition/MtTenant.java b/src/test/java/org/multitenant/partition/MtTenant.java new file mode 100644 index 000000000..9c21a14e0 --- /dev/null +++ b/src/test/java/org/multitenant/partition/MtTenant.java @@ -0,0 +1,67 @@ +package org.multitenant.partition; + +import io.ebean.annotation.Length; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Version; + +@Entity +public class MtTenant { + + @Id + final String id; + + @Length(50) + String name; + + @Length(50) + String email; + + String notes; + + @Version + long version; + + public MtTenant(String id, String name, String email) { + this.id = id; + this.name = name; + this.email = email; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getNotes() { + return notes; + } + + public void setNotes(String notes) { + this.notes = notes; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } +} diff --git a/src/test/java/org/multitenant/partition/MtTenantAware.java b/src/test/java/org/multitenant/partition/MtTenantAware.java new file mode 100644 index 000000000..ea6337a89 --- /dev/null +++ b/src/test/java/org/multitenant/partition/MtTenantAware.java @@ -0,0 +1,22 @@ +package org.multitenant.partition; + +import io.ebean.annotation.TenantId; + +import javax.persistence.ManyToOne; +import javax.persistence.MappedSuperclass; + +@MappedSuperclass +public abstract class MtTenantAware extends MtBaseDomain { + + @TenantId + @ManyToOne(optional = false) + MtTenant tenant; + + public MtTenant getTenant() { + return tenant; + } + + public void setTenant(MtTenant tenant) { + this.tenant = tenant; + } +} diff --git a/src/test/java/org/multitenant/partition/MultiTenantPartitionTest.java b/src/test/java/org/multitenant/partition/MultiTenantPartitionTest.java new file mode 100644 index 000000000..ff007a938 --- /dev/null +++ b/src/test/java/org/multitenant/partition/MultiTenantPartitionTest.java @@ -0,0 +1,80 @@ +package org.multitenant.partition; + +import io.ebean.EbeanServer; +import io.ebean.EbeanServerFactory; +import io.ebean.config.ServerConfig; +import io.ebean.config.TenantMode; +import org.ebeantest.LoggedSqlCollector; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MultiTenantPartitionTest { + + private static String[] names = {"Ace", "Base", "Case", "Dae", "Eva"}; + + static List tenants() { + List tenants = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + tenants.add(new MtTenant("ten_"+i, names[i], names[i]+"@foo.com".toLowerCase())); + } + return tenants; + } + + private static EbeanServer server = init(); + + static { + server.saveAll(tenants()); + } + + @Test + public void start() { + + UserContext.set("rob", "ten_1"); + + LoggedSqlCollector.start(); + MtContent content = new MtContent("first title"); + server.save(content); + + List sql = LoggedSqlCollector.current(); + assertThat(sql.get(0)).contains("insert into mt_content (title, body, when_modified, when_created, version, tenant_id) values (?,?,?,?,?,?)"); + + content.setBody("some body"); + server.save(content); + + sql = LoggedSqlCollector.current(); + assertThat(sql.get(0)).contains("update mt_content set body=?, when_modified=?, version=? where id=? and tenant_id=? and version=?"); + + server.delete(content); + + sql = LoggedSqlCollector.current(); + assertThat(sql.get(0)).contains("delete from mt_content where id=? and tenant_id=? and version=?"); + + LoggedSqlCollector.stop(); + + } + + + private static EbeanServer init() { + System.setProperty("ebean.ignoreExtraDdl", "true"); + + ServerConfig config = new ServerConfig(); + + config.setName("h2multitenant"); + config.loadFromProperties(); + config.setDdlGenerate(true); + config.setDdlRun(true); + config.setRegister(false); + config.setDefaultServer(false); + config.setCurrentTenantProvider(new CurrentTenant()); + config.setTenantMode(TenantMode.PARTITION); + + config.getClasses().add(MtTenant.class); + config.getClasses().add(MtContent.class); + + return EbeanServerFactory.create(config); + } +} diff --git a/src/test/java/org/multitenant/partition/UserContext.java b/src/test/java/org/multitenant/partition/UserContext.java new file mode 100644 index 000000000..60794b674 --- /dev/null +++ b/src/test/java/org/multitenant/partition/UserContext.java @@ -0,0 +1,46 @@ +package org.multitenant.partition; + +public final class UserContext { + + private static final UserContextThreadLocal local = new UserContextThreadLocal(); + + private String userId; + private String tenantId; + + private UserContext(String userId, String tenantId) { + this.userId = userId; + this.tenantId = tenantId; + } + + private UserContext() { + } + + public String getUserId() { + return userId; + } + + public String getTenantId() { + return tenantId; + } + + public static UserContext get() { + return local.get(); + } + + public static void reset() { + local.remove(); + } + + public static void set(String userId, String tenantId) { + local.set(new UserContext(userId, tenantId)); + } + + + private static class UserContextThreadLocal extends ThreadLocal { + + @Override + protected UserContext initialValue() { + return new UserContext(); + } + } +}