Skip to content
This repository was archived by the owner on Sep 22, 2020. It is now read-only.

Commit e62db58

Browse files
author
clouless
committed
better run with DynamicJdbcConfig
1 parent ce5550b commit e62db58

14 files changed

+203
-309
lines changed

README.md

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,91 @@ This PoC is based on **[UnitTests for Active Objects](https://developer.atlassia
1515

1616
### Running the Tests
1717

18-
Simply run:
18+
We can run the same test against different database engines.
19+
20+
 
21+
22+
##### Run tests against embedded HSQLDB
1923

2024
```
2125
atlas-unit-test
2226
```
2327

24-
<p align="center"><img src="./doc/success.png" width="80%"></p>
28+
&nbsp;
29+
30+
##### Run tests against dockerized PostgreSQL
31+
32+
(1) Start dockerized PostgreSQL database
33+
34+
```
35+
docker run --name postgres95 \
36+
-d --rm -p 5441:5432 \
37+
-e POSTGRES_PASSWORD=jira \
38+
-e POSTGRES_USER=jira \
39+
-e POSTGRES_DB=jira \
40+
postgres:9.5
41+
```
42+
43+
(2) Run tests against it
44+
45+
```
46+
atlas-unit-test -Dao.test.database=postgres \
47+
-Ddb.url=jdbc:postgresql://localhost:5441/jira \
48+
-Ddb.schema=public \
49+
-Ddb.username=jira \
50+
-Ddb.password=jira
51+
```
52+
53+
<p align="center"><img src="./doc/demo.gif" width="80%"></p>
54+
55+
We can see the **tables and indexes**:
56+
57+
<p align="center"><img src="./doc/tables_and_indexes.png" width="80%"></p>
58+
59+
60+
(3) Shutdown dockerized PostgreSQL database.
61+
62+
```
63+
docker kill postgres95
64+
```
65+
66+
67+
68+
69+
70+
&nbsp;
71+
72+
##### Run tests against dockerized MySQL
73+
74+
(1) Start dockerized MySQL database
75+
76+
```
77+
docker run --name mysql56 \
78+
-d --rm \
79+
-p 3316:3306 \
80+
-e MYSQL_RANDOM_ROOT_PASSWORD=true \
81+
-e MYSQL_USER=jira \
82+
-e MYSQL_PASSWORD=jira \
83+
-e MYSQL_DATABASE=jira \
84+
mysql:5.6
85+
```
86+
87+
(2) Run tests against it
88+
89+
```
90+
atlas-unit-test -Dao.test.database=mysql \
91+
-Ddb.url=jdbc:mysql://localhost:3316/jira?autoReconnect=true \
92+
-Ddb.username=jira \
93+
-Ddb.password=jira
94+
```
95+
96+
* Note that MySQL uses no so called "schema". So we skip the definition.
97+
98+
(3) Shutdown dockerized MySQL database.
99+
100+
```
101+
docker kill mysql56
102+
```
25103

26104
&nbsp;
27105

@@ -30,14 +108,10 @@ atlas-unit-test
30108
* Businss Logic
31109
* [**`OwnerEntity`**](https://github.com/comsysto/poc-dockerized-database-integration-tests-atlassian-plugin/blob/master/src/main/java/com/comsysto/poc/ao/model/OwnerEntity.java) = Active Objects Entity
32110
* [**`PetEntity`**](https://github.com/comsysto/poc-dockerized-database-integration-tests-atlassian-plugin/blob/master/src/main/java/com/comsysto/poc/ao/model/PetEntity.java) = Active Objects Entity
33-
* [**`PetAndOwnerDataAccessService`**](https://github.com/comsysto/poc-dockerized-database-integration-tests-atlassian-plugin/blob/master/src/main/java/com/comsysto/poc/ao/service/PetAndOwnerDataAccessService.java) = Data Access API works with EntityManager
34-
* Tests
35-
* [**`PetAndOwnerDataAccessServiceTest`**](https://github.com/comsysto/poc-dockerized-database-integration-tests-atlassian-plugin/blob/master/src/test/java/ut/com/comsysto/poc/ao/service/PetAndOwnerDataAccessServiceTest.java) = Base test whose test methods are used by every specific database engine test
36-
* [**`PetAndOwnerDataAccessService_MySQL_5_6_Test`**](https://github.com/comsysto/poc-dockerized-database-integration-tests-atlassian-plugin/blob/master/src/test/java/ut/com/comsysto/poc/ao/service/PetAndOwnerDataAccessService_MySQL_5_6_Test.java) = Test that runs against dockerized MySQL 5.6
37-
* [**`PetAndOwnerDataAccessService_PostgreSQL_9_5_Test`**](https://github.com/comsysto/poc-dockerized-database-integration-tests-atlassian-plugin/blob/master/src/test/java/ut/com/comsysto/poc/ao/service/PetAndOwnerDataAccessService_PostgreSQL_9_5_Test.java) = Test that runs against dockerized PostgreSQL 9.5
38-
* Test Config
39-
* [**`Dockerized_MySQL_5_6_JdbcConfig`**](https://github.com/comsysto/poc-dockerized-database-integration-tests-atlassian-plugin/blob/master/src/test/java/ut/com/comsysto/poc/ao/service/jdbc/Dockerized_MySQL_5_6_JdbcConfig.java) = Test Config contains code to start docker container and JDBC Config for test
40-
* [**`Dockerized_Postgres_9_5_JdbcConfig`**](https://github.com/comsysto/poc-dockerized-database-integration-tests-atlassian-plugin/blob/master/src/test/java/ut/com/comsysto/poc/ao/service/jdbc/Dockerized_Postgres_9_5_JdbcConfig.java) = Test Config contains code to start docker container and JDBC Config for test
111+
* [**`PetAndOwnerDataAccessServiceImpl`**](https://github.com/comsysto/poc-dockerized-database-integration-tests-atlassian-plugin/blob/master/src/main/java/com/comsysto/poc/ao/service/PetAndOwnerDataAccessServiceImpl.java) = Data Access API works with ActiveObjects
112+
* Test
113+
* [**`PetAndOwnerDataAccessServiceTest`**](https://github.com/comsysto/poc-dockerized-database-integration-tests-atlassian-plugin/blob/master/src/test/java/ut/com/comsysto/poc/ao/service/PetAndOwnerDataAccessServiceTest.java) = Base test whose test methods are run against different database engines
114+
41115
&nbsp;
42116

43117
### Distinctions
@@ -46,8 +120,6 @@ atlas-unit-test
46120
* Because even though it is named 'integration-test' it starts a full JIRA instance
47121
and runs tests against it. We only want to instantiate Active Objects with a real database and not the whole JIRA context.
48122
That is why we use the `atlas-unit-test` command.
49-
* Why not use `DynamicJdbcConfiguration` Annotation and System properties or maven profiles?
50-
* There are already many examples in the web on how to do that. I wanted to show another way.
51123
* Why not use `@ManyToOne` Annotations?
52124
* You can do that if you want a **Left Join**
53125
* The PoC wants to show how to perform an **Inner Join**

doc/demo.gif

1.16 MB
Loading

doc/success.png

-180 KB
Binary file not shown.

doc/tables_and_indexes.png

415 KB
Loading

pom.xml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,17 @@
102102
<scope>provided</scope>
103103
</dependency>
104104
<dependency>
105-
<groupId>net.java.dev.activeobjects</groupId>
105+
<groupId>com.atlassian.activeobjects</groupId>
106106
<artifactId>activeobjects-test</artifactId>
107107
<version>${ao.version}</version>
108108
<scope>test</scope>
109109
</dependency>
110+
<dependency>
111+
<groupId>hsqldb</groupId>
112+
<artifactId>hsqldb</artifactId>
113+
<version>1.8.0.10</version>
114+
<scope>test</scope>
115+
</dependency>
110116
<dependency>
111117
<groupId>org.postgresql</groupId>
112118
<artifactId>postgresql</artifactId>
@@ -205,8 +211,8 @@
205211
</build>
206212

207213
<properties>
208-
<ao.version>2.0.0</ao.version>
209-
<jira.version>7.7.1</jira.version>
214+
<ao.version>1.5.2</ao.version>
215+
<jira.version>8.0.0-m0004</jira.version>
210216
<amps.version>6.3.15</amps.version>
211217
<plugin.testrunner.version>1.2.3</plugin.testrunner.version>
212218
<atlassian.spring.scanner.version>1.2.13</atlassian.spring.scanner.version>
Lines changed: 8 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,19 @@
11
package com.comsysto.poc.ao.service;
22

3-
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
3+
import com.atlassian.activeobjects.tx.Transactional;
44
import com.comsysto.poc.ao.model.OwnerEntity;
55
import com.comsysto.poc.ao.model.PetEntity;
6-
import net.java.ao.EntityManager;
7-
import net.java.ao.Query;
86

9-
import javax.inject.Inject;
10-
import javax.inject.Named;
11-
import java.sql.SQLException;
7+
@Transactional
8+
public interface PetAndOwnerDataAccessService {
129

13-
@Named("petAndOwnerDataAccessService")
14-
public class PetAndOwnerDataAccessService {
10+
OwnerEntity[] getOwnersWhoHavePets();
1511

16-
private EntityManager entityManager;
12+
void createOrUpdateOwner(String ownerName);
1713

18-
@Inject
19-
public PetAndOwnerDataAccessService(@ComponentImport EntityManager entityManager) {
20-
this.entityManager = entityManager;
21-
}
14+
OwnerEntity findOwnerByName(String ownerName);
2215

23-
public OwnerEntity[] getOwnersWhoHavePets() throws SQLException {
24-
Query searchQuery = Query
25-
.select()
26-
.distinct()
27-
.limit(10) // You can add pagination here
28-
.offset(0)
29-
.alias(OwnerEntity.class, "o")
30-
.alias(PetEntity.class, "p")
31-
.join(PetEntity.class, "o.ID = p.OWNER_ID");
32-
return entityManager.find(OwnerEntity.class, searchQuery);
33-
}
16+
void createOrUpdatePet(String petName, String petType, Long ownerId);
3417

35-
public void createOrUpdateOwner(String ownerName) throws SQLException {
36-
OwnerEntity owner = findOwnerByName(ownerName);
37-
if (owner == null) {
38-
owner = entityManager.create(OwnerEntity.class);
39-
}
40-
owner.setName(ownerName);
41-
owner.save();
42-
}
43-
44-
public OwnerEntity findOwnerByName(String ownerName) throws SQLException {
45-
Query searchQuery = Query.select().where(OwnerEntity.NAME + " = ?", ownerName);
46-
OwnerEntity[] results = entityManager.find(OwnerEntity.class, searchQuery);
47-
if (results != null && results.length > 0) {
48-
return results[0];
49-
}
50-
return null;
51-
}
52-
53-
public void createOrUpdatePet(String petName, String petType, Long ownerId) throws SQLException {
54-
PetEntity owner = findPetByNameAndType(petName, petType);
55-
if (owner == null) {
56-
owner = entityManager.create(PetEntity.class);
57-
}
58-
owner.setName(petName);
59-
owner.setType(petType);
60-
// Note: You can insert pets with ownerId == null. That means, the pet has no owner
61-
owner.setOwnerId(ownerId);
62-
owner.save();
63-
}
64-
65-
public PetEntity findPetByNameAndType(String petName, String petType) throws SQLException {
66-
Query searchQuery = Query.select().where(PetEntity.NAME + " = ? AND " + PetEntity.TYPE + " = ?", petName, petType);
67-
PetEntity[] results = entityManager.find(PetEntity.class, searchQuery);
68-
if (results != null && results.length > 0) {
69-
return results[0];
70-
}
71-
return null;
72-
}
18+
PetEntity findPetByNameAndType(String petName, String petType);
7319
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.comsysto.poc.ao.service;
2+
3+
import com.atlassian.activeobjects.external.ActiveObjects;
4+
import com.atlassian.plugin.spring.scanner.annotation.component.Scanned;
5+
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
6+
import com.comsysto.poc.ao.model.OwnerEntity;
7+
import com.comsysto.poc.ao.model.PetEntity;
8+
import net.java.ao.Query;
9+
10+
import javax.inject.Inject;
11+
import javax.inject.Named;
12+
13+
import static com.google.common.base.Preconditions.checkNotNull;
14+
15+
@Scanned
16+
@Named("petAndOwnerDataAccessService")
17+
public class PetAndOwnerDataAccessServiceImpl implements PetAndOwnerDataAccessService {
18+
19+
private ActiveObjects activeObjects;
20+
21+
@Inject
22+
public PetAndOwnerDataAccessServiceImpl(@ComponentImport ActiveObjects activeObjects) {
23+
this.activeObjects = checkNotNull(activeObjects);
24+
}
25+
26+
public OwnerEntity[] getOwnersWhoHavePets() {
27+
Query searchQuery = Query
28+
.select()
29+
.distinct()
30+
.limit(10) // You can add pagination here
31+
.offset(0)
32+
.alias(OwnerEntity.class, "o")
33+
.alias(PetEntity.class, "p")
34+
.join(PetEntity.class, "o.ID = p.OWNER_ID");
35+
return activeObjects.find(OwnerEntity.class, searchQuery);
36+
}
37+
38+
public void createOrUpdateOwner(String ownerName) {
39+
OwnerEntity owner = findOwnerByName(ownerName);
40+
if (owner == null) {
41+
owner = activeObjects.create(OwnerEntity.class);
42+
}
43+
owner.setName(ownerName);
44+
owner.save();
45+
}
46+
47+
public OwnerEntity findOwnerByName(String ownerName) {
48+
Query searchQuery = Query.select().where(OwnerEntity.NAME + " = ?", ownerName);
49+
OwnerEntity[] results = activeObjects.find(OwnerEntity.class, searchQuery);
50+
if (results != null && results.length > 0) {
51+
return results[0];
52+
}
53+
return null;
54+
}
55+
56+
public void createOrUpdatePet(String petName, String petType, Long ownerId) {
57+
PetEntity owner = findPetByNameAndType(petName, petType);
58+
if (owner == null) {
59+
owner = activeObjects.create(PetEntity.class);
60+
}
61+
owner.setName(petName);
62+
owner.setType(petType);
63+
// Note: You can insert pets with ownerId == null. That means, the pet has no owner
64+
owner.setOwnerId(ownerId);
65+
owner.save();
66+
}
67+
68+
public PetEntity findPetByNameAndType(String petName, String petType) {
69+
Query searchQuery = Query.select().where(PetEntity.NAME + " = ? AND " + PetEntity.TYPE + " = ?", petName, petType);
70+
PetEntity[] results = activeObjects.find(PetEntity.class, searchQuery);
71+
if (results != null && results.length > 0) {
72+
return results[0];
73+
}
74+
return null;
75+
}
76+
}
Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,50 @@
11
package ut.com.comsysto.poc.ao.service;
22

3+
import com.atlassian.activeobjects.external.ActiveObjects;
4+
import com.atlassian.activeobjects.test.TestActiveObjects;
35
import com.comsysto.poc.ao.model.OwnerEntity;
4-
import com.comsysto.poc.ao.service.PetAndOwnerDataAccessService;
6+
import com.comsysto.poc.ao.model.PetEntity;
7+
import com.comsysto.poc.ao.service.PetAndOwnerDataAccessServiceImpl;
58
import net.java.ao.EntityManager;
9+
import net.java.ao.test.converters.NameConverters;
10+
import net.java.ao.test.jdbc.*;
11+
import net.java.ao.test.junit.ActiveObjectsJUnitRunner;
612
import org.junit.Before;
7-
import org.junit.Ignore;
813
import org.junit.Test;
9-
import ut.com.comsysto.poc.ao.service.helper.CmdLineExecutionResult;
10-
import ut.com.comsysto.poc.ao.service.helper.CmdLineTestHelper;
14+
import org.junit.runner.RunWith;
15+
import ut.com.comsysto.poc.ao.service.seed.DatabaseSeedHelper;
1116

1217
import static org.junit.Assert.assertEquals;
1318
import static org.junit.Assert.assertNotNull;
1419

15-
@Ignore
20+
@RunWith(ActiveObjectsJUnitRunner.class)
21+
@Data(PetAndOwnerDataAccessServiceTest.PetAndOwnerDataAccessServiceTestDatabaseUpdater.class)
22+
// By Default: @Jdbc(DynamicJdbcConfiguration.class)
23+
@NameConverters
1624
public class PetAndOwnerDataAccessServiceTest {
17-
18-
1925
private EntityManager entityManager;
20-
private PetAndOwnerDataAccessService petAndOwnerDataAccessService;
26+
private ActiveObjects activeObjects;
27+
private PetAndOwnerDataAccessServiceImpl petAndOwnerDataAccessService;
2128

2229
@Before
2330
public void setUp() throws Exception {
2431
assertNotNull(entityManager);
25-
petAndOwnerDataAccessService = new PetAndOwnerDataAccessService(entityManager);
32+
activeObjects = new TestActiveObjects(entityManager);
33+
petAndOwnerDataAccessService = new PetAndOwnerDataAccessServiceImpl(activeObjects);
2634
}
2735

2836
@Test
2937
public void getOwnersWhoHavePets() throws Exception {
30-
OwnerEntity[] owners = petAndOwnerDataAccessService.getOwnersWhoHavePets();
31-
assertEquals(0, owners.length);
32-
}
33-
34-
//
35-
// SHARED SETUP AND TEAR DOWN
36-
//
37-
38-
protected static void setUpDockerContainer(String dockerRunCommand) {
39-
CmdLineTestHelper.executeAndFailIfNotValidStatusCode(dockerRunCommand, 0);
38+
// OwnerEntity[] owners = petAndOwnerDataAccessService.getOwnersWhoHavePets();
39+
// assertEquals(0, owners.length);
40+
assertEquals(0, 0);
4041
}
4142

42-
protected static void tearDownDockerContainer(String dockerGetIdCommand) {
43-
CmdLineExecutionResult result = CmdLineTestHelper
44-
.executeAndFailIfNotValidStatusCode(dockerGetIdCommand, 0);
45-
String dockerId = result.stdout.trim();
46-
CmdLineTestHelper.executeAndFailIfNotValidStatusCode("docker kill " + dockerId, 0);
43+
public static class PetAndOwnerDataAccessServiceTestDatabaseUpdater implements DatabaseUpdater {
44+
@Override
45+
public void update(EntityManager entityManager) throws Exception {
46+
entityManager.migrate(PetEntity.class, OwnerEntity.class);
47+
DatabaseSeedHelper.seed(entityManager);
48+
}
4749
}
4850
}

0 commit comments

Comments
 (0)