Add template for assignment 1

This commit is contained in:
Philipp Raith 2021-03-10 08:14:26 +01:00
parent 4147115ba2
commit 720d6c193f
103 changed files with 6357 additions and 0 deletions

36
ass1-doc/pom.xml Normal file
View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>at.ac.tuwien.infosys.dst</groupId>
<artifactId>dst</artifactId>
<version>2021.1</version>
<relativePath>..</relativePath>
</parent>
<artifactId>ass1-doc</artifactId>
<packaging>jar</packaging>
<name>DST :: Assignment 1 :: Document DB</name>
<dependencies>
<dependency>
<groupId>at.ac.tuwien.infosys.dst</groupId>
<artifactId>ass1-jpa</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,15 @@
package dst.ass1.doc;
import org.bson.Document;
import java.util.List;
public interface IDocumentQuery {
Document findLocationById(Long locationId);
List<Long> findIdsByNameAndRadius(String name, double longitude, double latitude, double radius);
List<Document> getDocumentStatistics();
}

View File

@ -0,0 +1,11 @@
package dst.ass1.doc;
import dst.ass1.jpa.model.ILocation;
import java.util.Map;
public interface IDocumentRepository {
void insert(ILocation location, Map<String, Object> locationProperties);
}

View File

@ -0,0 +1,11 @@
package dst.ass1.doc;
import com.mongodb.client.MongoDatabase;
public interface IDocumentServiceFactory {
IDocumentQuery createDocumentQuery(MongoDatabase db);
IDocumentRepository createDocumentRepository();
}

View File

@ -0,0 +1,21 @@
package dst.ass1.doc.impl;
import com.mongodb.client.MongoDatabase;
import dst.ass1.doc.IDocumentQuery;
import dst.ass1.doc.IDocumentRepository;
import dst.ass1.doc.IDocumentServiceFactory;
public class DocumentServiceFactory implements IDocumentServiceFactory {
@Override
public IDocumentQuery createDocumentQuery(MongoDatabase db) {
// TODO
return null;
}
@Override
public IDocumentRepository createDocumentRepository() {
// TODO
return null;
}
}

View File

@ -0,0 +1,45 @@
package dst.ass1.doc;
import com.mongodb.client.MongoDatabase;
import dst.ass1.jpa.util.Constants;
import org.bson.Document;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Objects;
import java.util.Scanner;
public class DocumentTestData implements IDocumentTestData {
private String documentResource;
public DocumentTestData() {
this("documents.json");
}
public DocumentTestData(String documentResource) {
this.documentResource = documentResource;
}
@SuppressWarnings("unchecked")
@Override
public void insertTestData(MongoDatabase db) throws IOException {
URL resource = Objects.requireNonNull(getDocumentsResource());
String testDataJson = readFully(resource);
List<Document> documents = Document.parse(testDataJson).get("documents", List.class);
db.getCollection(Constants.COLL_LOCATION_DATA).insertMany(documents);
}
private URL getDocumentsResource() {
return getClass().getClassLoader().getResource(documentResource);
}
private String readFully(URL resource) throws IOException {
try (Scanner scanner = new Scanner(resource.openStream())) {
return scanner.useDelimiter("\\Z").next();
}
}
}

View File

@ -0,0 +1,56 @@
package dst.ass1.doc;
import de.flapdoodle.embed.mongo.config.MongodConfig;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.IFeatureAwareVersion;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.mongo.tests.MongodForTestsFactory;
import org.junit.rules.ExternalResource;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
/**
* JUnit rule that creates an in-memory instance of MongoDB using the flapdoodle Embedded MongoDB.
*/
public class EmbeddedMongo extends ExternalResource {
private MongodForTestsFactory mongod;
@Override
protected void before() throws Throwable {
requirePort();
mongod = new MongodFactory(); // starts process in constructor
}
@Override
protected void after() {
if (mongod != null) {
mongod.shutdown();
}
}
private void requirePort() throws IOException, IllegalStateException {
try (ServerSocket ignore = new ServerSocket(27017)) {
// ignore
} catch (BindException e) {
throw new IllegalStateException("Could not bind port 27017 which is necessary to run the MongoDB tests", e);
}
}
public static class MongodFactory extends MongodForTestsFactory {
public MongodFactory() throws IOException {
super(Version.Main.V3_5);
}
@Override
protected MongodConfig newMongodConfig(IFeatureAwareVersion version) throws IOException {
return MongodConfig.builder()
.net(new Net(27017, false))
.version(version)
.build();
}
}
}

View File

@ -0,0 +1,18 @@
package dst.ass1.doc;
import com.mongodb.client.MongoDatabase;
// DO NOT MODIFY THIS CLASS.
/**
* The IDocumentTestData interface works like the ITestData as introduced in ass1-jpa only for the {@link MongoService}.
*/
public interface IDocumentTestData {
/**
* Inserts the data into the given MongoDatabase instance.
*
* @param db the mongo database instance
* @throws Exception if the insertion failed for some reason
*/
void insertTestData(MongoDatabase db) throws Exception;
}

View File

@ -0,0 +1,41 @@
package dst.ass1.doc;
import dst.ass1.jpa.model.ILocation;
public class MockLocation implements ILocation {
private Long id;
private String name;
private Long LocationId;
@Override
public Long getId() {
return id;
}
@Override
public void setId(Long id) {
this.id = id;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public Long getLocationId() {
return LocationId;
}
@Override
public void setLocationId(Long locationId) {
LocationId = locationId;
}
}

View File

@ -0,0 +1,124 @@
package dst.ass1.doc;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import dst.ass1.doc.impl.DocumentServiceFactory;
import dst.ass1.jpa.util.Constants;
import org.bson.Document;
import org.junit.rules.ExternalResource;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
// DO NOT MODIFY THIS CLASS.
/**
* The MongoService class is used as a JUnit rule, that fulfills the same tasks as the ORMService in ass1-jpa, and works
* very similarly.
*/
public class MongoService extends ExternalResource {
private IDocumentTestData testData;
private boolean insertTestData;
private boolean clearTestData;
private MongoClient mongoClient;
private MongoDatabase mongoDatabase;
private IDocumentServiceFactory documentServiceFactory;
private IDocumentRepository documentRepository;
private IDocumentQuery documentQuery;
public MongoService() {
this(null, false, true);
}
public MongoService(IDocumentTestData testData) {
this(testData, true, true);
}
public MongoService(IDocumentTestData testData, boolean insertTestData, boolean clearTestData) {
this.testData = testData;
this.insertTestData = insertTestData;
this.clearTestData = clearTestData;
}
public static Stream<Document> stream(MongoCollection<Document> collection) {
return StreamSupport.stream(collection.find().spliterator(), false);
}
public static <T> Map<T, Document> idMap(MongoCollection<Document> collection, Function<Document, T> idFunction) {
return stream(collection).collect(Collectors.toMap(idFunction, Function.identity()));
}
public MongoClient getMongoClient() {
return mongoClient;
}
public MongoDatabase getMongoDatabase() {
return mongoDatabase;
}
public IDocumentServiceFactory getDocumentServiceFactory() {
return documentServiceFactory;
}
public IDocumentRepository getDocumentRepository() {
return documentRepository;
}
public IDocumentQuery getDocumentQuery() {
return documentQuery;
}
@Override
protected void before() throws Throwable {
setUpMongo();
if (insertTestData && testData != null) {
insertData(testData);
}
}
@Override
protected void after() {
try {
if (clearTestData) {
clearData();
}
} finally {
tearDownMongo();
}
}
private void setUpMongo() {
mongoClient = new MongoClient("127.0.0.1");
mongoDatabase = mongoClient.getDatabase(Constants.MONGO_DB_NAME);
documentServiceFactory = new DocumentServiceFactory();
documentRepository = documentServiceFactory.createDocumentRepository();
if (documentRepository == null) {
throw new IllegalStateException("DocumentRepository returned from factory is null");
}
documentQuery = documentServiceFactory.createDocumentQuery(mongoDatabase);
}
private void tearDownMongo() {
mongoClient.close();
}
private void insertData(IDocumentTestData testData) throws Exception {
testData.insertTestData(getMongoDatabase());
}
private void clearData() {
getMongoDatabase().drop();
}
}

View File

@ -0,0 +1,128 @@
package dst.ass1.doc.tests;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import dst.ass1.doc.EmbeddedMongo;
import dst.ass1.doc.IDocumentRepository;
import dst.ass1.doc.MockLocation;
import dst.ass1.doc.MongoService;
import dst.ass1.jpa.util.Constants;
import org.bson.Document;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
public class Ass1_4_1Test {
public static final String LOCATION_NAME_1 = "testName1";
public static final String LOCATION_NAME_2 = "testName2";
public static final Long LOCATION_ID_1 = 1L;
public static final Long LOCATION_ID_2 = 2L;
public static final Double GEO_1_1 = 16.3699;
public static final Double GEO_1_2 = 48.199;
public static final Double GEO_2_1 = 16.368528;
public static final Double GEO_2_2 = 48.200939;
@ClassRule
public static EmbeddedMongo embeddedMongo = new EmbeddedMongo();
@Rule
public MongoService mongo = new MongoService();
private MockLocation l1;
private MockLocation l2;
private Map<String, Object> l1Properties;
private Map<String, Object> l2Properties;
private Map<String, Object> geo1;
private Map<String, Object> geo2;
@Before
public void setUp() {
l1 = new MockLocation();
l1.setName(LOCATION_NAME_1);
l1.setLocationId(LOCATION_ID_1);
l2 = new MockLocation();
l2.setName(LOCATION_NAME_2);
l2.setLocationId(LOCATION_ID_2);
l1Properties = new HashMap<>();
geo1 = new HashMap<>();
geo1.put("type", "Point");
geo1.put("coordinates", Arrays.asList(GEO_1_1, GEO_1_2));
l1Properties.put("type", "place");
l1Properties.put("geo", geo1);
l1Properties.put("1337", "7331");
l1Properties.put("Foo", "Bar");
l1Properties.put("Complex", Arrays.asList(1, 2, 3, 5, 8));
l2Properties = new HashMap<>();
geo2 = new HashMap<>();
geo2.put("type", "Point");
geo2.put("coordinates", Arrays.asList(GEO_2_1, GEO_2_2));
l2Properties.put("type", "place");
l2Properties.put("geo", geo2);
l2Properties.put("123456", "654321");
l2Properties.put("F00", "B@r");
l2Properties.put("Complex2", Arrays.asList(4, 6, 7, 9));
}
@Test
public void insert_insertsDocumentsCorrectly() throws Exception {
IDocumentRepository documentRepository = mongo.getDocumentRepository();
MongoDatabase mongoDatabase = mongo.getMongoDatabase();
documentRepository.insert(l1, l1Properties);
documentRepository.insert(l2, l2Properties);
MongoCollection<Document> collection = mongoDatabase.getCollection(Constants.COLL_LOCATION_DATA);
Map<Long, Document> map = MongoService.idMap(collection, d -> d.getLong(Constants.I_LOCATION));
assertNotNull(map);
assertEquals(2, map.size());
Document document1 = map.get(1L);
assertEquals(LOCATION_ID_1, document1.get(Constants.I_LOCATION));
assertEquals(LOCATION_NAME_1, document1.get(Constants.M_LOCATION_NAME));
assertEquals("7331", document1.get("1337"));
assertEquals("Bar", document1.get("Foo"));
assertEquals(Arrays.asList(1, 2, 3, 5, 8), document1.get("Complex"));
assertEquals("place", document1.get("type"));
Map<String, Object> geo1Retrieved = document1.get("geo", new HashMap<>());
assertEquals(2, geo1Retrieved.size());
assertEquals("Point", geo1Retrieved.get("type"));
List<Double> coordinates1 = (List<Double>) geo1Retrieved.get("coordinates");
assertEquals(2, coordinates1.size());
assertThat(coordinates1, hasItems(GEO_1_1, GEO_1_2));
Document document2 = map.get(2L);
assertEquals(LOCATION_ID_2, document2.get(Constants.I_LOCATION));
assertEquals(LOCATION_NAME_2, document2.get(Constants.M_LOCATION_NAME));
assertEquals("654321", document2.get("123456"));
assertEquals("B@r", document2.get("F00"));
assertEquals(Arrays.asList(4, 6, 7, 9), document2.get("Complex2"));
assertEquals("place", document2.get("type"));
Map<String, Object> geo2Retrieved = document2.get("geo", new HashMap<>());
assertEquals(2, geo2Retrieved.size());
assertEquals("Point", geo2Retrieved.get("type"));
List<Double> coordinates2 = (List<Double>) geo2Retrieved.get("coordinates");
assertEquals(2, coordinates2.size());
assertThat(coordinates2, hasItems(GEO_2_1, GEO_2_2));
}
}

View File

@ -0,0 +1,53 @@
package dst.ass1.doc.tests;
import dst.ass1.doc.DocumentTestData;
import dst.ass1.doc.EmbeddedMongo;
import dst.ass1.doc.IDocumentQuery;
import dst.ass1.doc.MongoService;
import dst.ass1.jpa.util.Constants;
import org.bson.Document;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.*;
public class Ass1_4_2aTest {
@ClassRule
public static EmbeddedMongo embeddedMongo = new EmbeddedMongo();
@Rule
public MongoService mongo = new MongoService(new DocumentTestData());
@SuppressWarnings("unchecked")
@Test
public void findByLocationId_returnsCorrectDocument() {
IDocumentQuery documentQuery = mongo.getDocumentQuery();
Document location = documentQuery.findLocationById(2L);
assertNotNull(location);
assertEquals(2L, (long) location.getLong(Constants.I_LOCATION));
assertEquals("McDonald's", location.getString(Constants.M_LOCATION_NAME));
assertEquals("place", location.getString("type"));
assertEquals("Restaurant", location.getString("category"));
Document geo = location.get("geo", Document.class);
assertNotNull(geo);
List<Double> coordinates = geo.getList("coordinates", Double.class);
assertNotNull(coordinates);
assertEquals(2, coordinates.size());
assertEquals("Point", geo.getString("type"));
assertEquals(16.368528, coordinates.get(0), 0.0);
assertEquals(48.200939, coordinates.get(1), 0.0);
}
@Test
public void findByLocationId_withInvalidId_returnsNull() throws Exception {
Document material = mongo.getDocumentQuery().findLocationById(1337L);
assertNull(material);
}
}

View File

@ -0,0 +1,43 @@
package dst.ass1.doc.tests;
import dst.ass1.doc.DocumentTestData;
import dst.ass1.doc.EmbeddedMongo;
import dst.ass1.doc.MongoService;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import java.util.List;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
public class Ass1_4_2bTest {
@ClassRule
public static EmbeddedMongo embeddedMongo = new EmbeddedMongo();
@Rule
public MongoService mongo = new MongoService(new DocumentTestData());
@Test
public void findIdsByNameAndRadius_returnsCorrectLocationIds() throws Exception {
List<Long> locationIds = mongo.getDocumentQuery().findIdsByNameAndRadius("McD", 16.367873, 48.198763, 1000);
assertFalse(locationIds.isEmpty());
assertThat(locationIds, hasItems(2L, 3L, 4L));
}
@Test
public void findIdsByType_withNonExistingType_returnsNoLocationIds() throws Exception {
List<Long> locationIds = mongo.getDocumentQuery().findIdsByNameAndRadius("McD", 16.367873, 48.198763, 5);
assertNotNull(locationIds);
assertTrue(locationIds.isEmpty());
locationIds = mongo.getDocumentQuery().findIdsByNameAndRadius("NONEXISTING", 16.367873, 48.198763, 2000);
assertNotNull(locationIds);
assertTrue(locationIds.isEmpty());
}
}

View File

@ -0,0 +1,39 @@
package dst.ass1.doc.tests;
import dst.ass1.doc.EmbeddedMongo;
import dst.ass1.doc.MongoService;
import dst.ass1.jpa.util.Constants;
import org.bson.Document;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import java.util.List;
import java.util.stream.StreamSupport;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class Ass1_4_3_01Test {
@ClassRule
public static EmbeddedMongo embeddedMongo = new EmbeddedMongo();
@Rule
public MongoService mongo = new MongoService(db -> {
boolean exists = StreamSupport.stream(db.listCollectionNames().spliterator(), false)
.anyMatch(Constants.COLL_LOCATION_DATA::equalsIgnoreCase);
if (!exists) {
db.createCollection(Constants.COLL_LOCATION_DATA); // make sure the empty collection exists
}
});
@Test
public void getDocumentStatistics_withEmptyData_returnsEmptyStatistics() throws Exception {
List<Document> documentStatistics = mongo.getDocumentQuery().getDocumentStatistics();
assertNotNull(documentStatistics);
assertTrue(documentStatistics.isEmpty());
}
}

View File

@ -0,0 +1,46 @@
package dst.ass1.doc.tests;
import dst.ass1.doc.DocumentTestData;
import dst.ass1.doc.EmbeddedMongo;
import dst.ass1.doc.MongoService;
import org.bson.Document;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
public class Ass1_4_3_02Test {
@ClassRule
public static EmbeddedMongo embeddedMongo = new EmbeddedMongo();
@Rule
public MongoService mongo = new MongoService(new DocumentTestData());
@Test
public void getDocumentStatistics_returnsCorrectStatistics() throws Exception {
List<Document> documentStatistics = mongo.getDocumentQuery().getDocumentStatistics();
assertNotNull(documentStatistics);
assertEquals(3, documentStatistics.size());
List<String> types = documentStatistics.stream().map(d -> d.getString("_id")).collect(Collectors.toList());
assertThat("expected three aggregation keys", types, hasItems("Restaurant", "Park", "University"));
Map<String, Double> dsMap = documentStatistics.stream().collect(Collectors.toMap(
d -> d.getString("_id"),
d -> d.getDouble("value"))
);
assertEquals(4.0d, dsMap.get("Restaurant"), 0);
assertEquals(1.0d, dsMap.get("Park"), 0);
assertEquals(7.0d, dsMap.get("University"), 0);
}
}

View File

@ -0,0 +1,16 @@
package dst.ass1.doc.tests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses( {
Ass1_4_1Test.class,
Ass1_4_2aTest.class,
Ass1_4_2bTest.class,
Ass1_4_3_01Test.class,
Ass1_4_3_02Test.class
})
public class Ass1_4_Suite {
}

View File

@ -0,0 +1,184 @@
{
"documents": [
{
"location_id": NumberLong(1),
"type": "place",
"name": "TU Wien",
"geo": {
"type": "Point",
"coordinates": [
16.3699,
48.199
]
},
"category": "University"
},
{
"location_id": NumberLong(2),
"type": "place",
"name": "McDonald's",
"geo": {
"type": "Point",
"coordinates": [
16.368528,
48.200939
]
},
"category": "Restaurant"
},
{
"location_id": NumberLong(3),
"type": "place",
"name": "McDonald's",
"geo": {
"type": "Point",
"coordinates": [
16.374138,
48.201085
]
},
"category": "Restaurant"
},
{
"location_id": NumberLong(4),
"type": "place",
"name": "McDonald's",
"geo": {
"type": "Point",
"coordinates": [
16.371674,
48.205241
]
},
"category": "Restaurant"
},
{
"location_id": NumberLong(5),
"type": "place",
"name": "McDonald's",
"geo": {
"type": "Point",
"coordinates": [
16.380754,
48.219325
]
},
"category": "Restaurant"
},
{
"location_id": NumberLong(6),
"type": "address",
"name": "Zirkusgasse 1",
"geo": {
"type": "Point",
"coordinates": [
16.384230,
48.216310
]
}
},
{
"location_id": NumberLong(7),
"type": "address",
"name": "Handelskai 9",
"geo": {
"type": "Point",
"coordinates": [
16.406082,
48.225571
]
}
},
{
"location_id": NumberLong(8),
"type": "place",
"name": "Cairngorms National Park",
"geo": {
"type": "Point",
"coordinates": [
-3.562790,
57.046944
]
},
"category": "Park"
},
{
"location_id": NumberLong(9),
"type": "place",
"name": "Distributed Systems Group",
"geo": {
"type": "Point",
"coordinates": [
16.371425,
48.197742
]
},
"category": "University"
},
{
"location_id": NumberLong(10),
"type": "place",
"name": "Computer Vision Lab",
"geo": {
"type": "Point",
"coordinates": [
16.369572,
48.195244
]
},
"category": "University"
},
{
"location_id": NumberLong(11),
"type": "place",
"name": "Uni Wien",
"geo": {
"type": "Point",
"coordinates": [
16.360372,
48.213069
]
},
"category": "University"
},
{
"location_id": NumberLong(12),
"type": "place",
"name": "BOKU Wien",
"geo": {
"type": "Point",
"coordinates": [
16.337443,
48.236530
]
},
"category": "University"
},
{
"location_id": NumberLong(13),
"type": "place",
"name": "WU Wien",
"geo": {
"type": "Point",
"coordinates": [
16.408456,
48.213561
]
},
"category": "University"
},
{
"location_id": NumberLong(14),
"type": "place",
"name": "Audimax TU Wien",
"geo": {
"type": "Point",
"coordinates": [
16.363949,
48.200822
]
},
"category": "University"
}
]
}

View File

@ -0,0 +1,17 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - %highlight(%5p) [%12.12thread] %cyan(%-40.40logger{39}): %m%n</pattern>
</encoder>
</appender>
<logger name="org.mongodb.driver" level="WARN"/>
<logger name="de.flapdoodle.embed" level="WARN"/>
<root level="${log.level:-INFO}">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

35
ass1-jpa/pom.xml Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>at.ac.tuwien.infosys.dst</groupId>
<artifactId>dst</artifactId>
<version>2021.1</version>
<relativePath>..</relativePath>
</parent>
<artifactId>ass1-jpa</artifactId>
<packaging>jar</packaging>
<name>DST :: Assignment 1 :: JPA</name>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,9 @@
package dst.ass1.jpa.dao;
import java.util.List;
public interface GenericDAO<T> {
T findById(Long id);
List<T> findAll();
}

View File

@ -0,0 +1,23 @@
package dst.ass1.jpa.dao;
public interface IDAOFactory {
IDriverDAO createDriverDAO();
IEmploymentDAO createEmploymentDAO();
ILocationDAO createLocationDAO();
IMatchDAO createMatchDAO();
IOrganizationDAO createOrganizationDAO();
IRiderDAO createRiderDAO();
ITripDAO createTripDAO();
ITripInfoDAO createTripInfoDAO();
IVehicleDAO createVehicleDAO();
}

View File

@ -0,0 +1,19 @@
package dst.ass1.jpa.dao;
import dst.ass1.jpa.model.IDriver;
import java.util.Collection;
public interface IDriverDAO extends GenericDAO<IDriver> {
/**
* Find all drivers that have active employments (active at least one month) in more than the given number
* of organizations
*
* @param numberOfOrganizations number of organizations
* @return a collection containing drivers
*/
Collection<IDriver> findActiveInMultipleOrganizationsDrivers(Long numberOfOrganizations);
}

View File

@ -0,0 +1,6 @@
package dst.ass1.jpa.dao;
import dst.ass1.jpa.model.IEmployment;
public interface IEmploymentDAO extends GenericDAO<IEmployment> {
}

View File

@ -0,0 +1,16 @@
package dst.ass1.jpa.dao;
import dst.ass1.jpa.model.ILocation;
import java.util.Collection;
public interface ILocationDAO extends GenericDAO<ILocation> {
/**
* Finds all distinct Location.locationId that have been reached as a Trip destination or additional
* stops. Only takes completed trips in account.
*
* @return a list containing Location.locationIds
*/
Collection<Long> findReachedLocationIds();
}

View File

@ -0,0 +1,6 @@
package dst.ass1.jpa.dao;
import dst.ass1.jpa.model.IMatch;
public interface IMatchDAO extends GenericDAO<IMatch> {
}

View File

@ -0,0 +1,6 @@
package dst.ass1.jpa.dao;
import dst.ass1.jpa.model.IOrganization;
public interface IOrganizationDAO extends GenericDAO<IOrganization> {
}

View File

@ -0,0 +1,33 @@
package dst.ass1.jpa.dao;
import dst.ass1.jpa.model.IMoney;
import dst.ass1.jpa.model.IRider;
import java.util.Map;
public interface IRiderDAO extends GenericDAO<IRider> {
/**
* Returns the rider associated with the given email. Returns null if the email does not exist.
*
* @param email the email address
* @return the rider or null
*/
IRider findByEmail(String email);
/**
* Gets the total travel distance of the rider with the most recently completed trip
*
* @return the total distance the rider has travelled
*/
Double getTotalDistanceOfMostRecentRider();
/**
* Finds for each Rider, who has completed at least one trip in the past 30 days, the sum of their total
* spendings of the past 30 days.
*
* @return a map containing each rider, and the money grouped by their currency.
*/
Map<IRider, Map<String, IMoney>> getRecentSpending();
}

View File

@ -0,0 +1,18 @@
package dst.ass1.jpa.dao;
import dst.ass1.jpa.model.ITrip;
import java.util.Collection;
import java.util.Date;
public interface ITripDAO extends GenericDAO<ITrip> {
/**
* Find all canceled trips that were created in the given date range.
*
* @param start start of the date range
* @param end end of the date range
* @return the cancelled trips
*/
Collection<ITrip> findCancelledTrips(Date start, Date end);
}

View File

@ -0,0 +1,6 @@
package dst.ass1.jpa.dao;
import dst.ass1.jpa.model.ITripInfo;
public interface ITripInfoDAO extends GenericDAO<ITripInfo> {
}

View File

@ -0,0 +1,6 @@
package dst.ass1.jpa.dao;
import dst.ass1.jpa.model.IVehicle;
public interface IVehicleDAO extends GenericDAO<IVehicle> {
}

View File

@ -0,0 +1,74 @@
package dst.ass1.jpa.dao.impl;
import dst.ass1.jpa.dao.*;
import javax.persistence.EntityManager;
public class DAOFactory implements IDAOFactory {
/*
* HINT: When using the org.hibernate.Session in your DAOs you can extract it from the EntityManager reference with
* e.g., em.unwrap(org.hibernate.Session.class). Do not store this org.hibernate.Session in your DAOs, but unwrap it
* every time you actually need it.
*/
private EntityManager em;
public DAOFactory(EntityManager em) {
this.em = em;
}
@Override
public IDriverDAO createDriverDAO() {
// TODO
return null;
}
@Override
public IEmploymentDAO createEmploymentDAO() {
// TODO
return null;
}
@Override
public ILocationDAO createLocationDAO() {
// TODO
return null;
}
@Override
public IMatchDAO createMatchDAO() {
// TODO
return null;
}
@Override
public IOrganizationDAO createOrganizationDAO() {
// TODO
return null;
}
@Override
public IRiderDAO createRiderDAO() {
// TODO
return null;
}
@Override
public ITripDAO createTripDAO() {
// TODO
return null;
}
@Override
public ITripInfoDAO createTripInfoDAO() {
// TODO
return null;
}
@Override
public IVehicleDAO createVehicleDAO() {
// TODO
return null;
}
}

View File

@ -0,0 +1,33 @@
package dst.ass1.jpa.interceptor;
import org.hibernate.EmptyInterceptor;
public class SQLInterceptor extends EmptyInterceptor {
private static final long serialVersionUID = -3082243834965597947L;
public static void resetCounter() {
// TODO
}
public static int getSelectCount() {
// TODO
return -1;
}
/**
* If the verbose argument is set, the interceptor prints the intercepted SQL statements to System.out.
*
* @param verbose whether or not to be verbose
*/
public static void setVerbose(boolean verbose) {
// TODO
}
@Override
public String onPrepareStatement(String sql) {
// TODO
return sql;
}
}

View File

@ -0,0 +1,44 @@
package dst.ass1.jpa.listener;
public class DefaultListener {
// TODO
public static int getLoadOperations() {
// TODO
return -1;
}
public static int getUpdateOperations() {
// TODO
return -1;
}
public static int getRemoveOperations() {
// TODO
return -1;
}
public static int getPersistOperations() {
// TODO
return -1;
}
public static long getOverallTimeToPersist() {
// TODO
return -1;
}
public static double getAverageTimeToPersist() {
// TODO
return -1;
}
/**
* Clears the internal data structures that are used for storing the operations.
*/
public static void clear() {
// TODO
}
}

View File

@ -0,0 +1,17 @@
package dst.ass1.jpa.model;
import java.util.Collection;
public interface IDriver extends IPlatformUser {
Collection<IEmployment> getEmployments();
void setEmployments(Collection<IEmployment> employments);
void addEmployment(IEmployment employment);
IVehicle getVehicle();
void setVehicle(IVehicle vehicle);
}

View File

@ -0,0 +1,18 @@
package dst.ass1.jpa.model;
import java.util.Date;
public interface IEmployment {
IEmploymentKey getId();
void setId(IEmploymentKey employmentKey);
Date getSince();
void setSince(Date since);
Boolean isActive();
void setActive(Boolean active);
}

View File

@ -0,0 +1,12 @@
package dst.ass1.jpa.model;
public interface IEmploymentKey {
IDriver getDriver();
void setDriver(IDriver driver);
IOrganization getOrganization();
void setOrganization(IOrganization organization);
}

View File

@ -0,0 +1,16 @@
package dst.ass1.jpa.model;
public interface ILocation {
Long getId();
void setId(Long id);
String getName();
void setName(String name);
Long getLocationId();
void setLocationId(Long locationId);
}

View File

@ -0,0 +1,30 @@
package dst.ass1.jpa.model;
import java.util.Date;
public interface IMatch {
Long getId();
void setId(Long id);
Date getDate();
void setDate(Date date);
IMoney getFare();
void setFare(IMoney money);
ITrip getTrip();
void setTrip(ITrip trip);
IVehicle getVehicle();
void setVehicle(IVehicle vehicle);
IDriver getDriver();
void setDriver(IDriver driver);
}

View File

@ -0,0 +1,30 @@
package dst.ass1.jpa.model;
public interface IModelFactory {
IModelFactory createModelFactory();
IDriver createDriver();
IEmployment createEmployment();
IEmploymentKey createEmploymentKey();
ILocation createLocation();
IMatch createMatch();
IMoney createMoney();
IOrganization createOrganization();
IRider createRider();
IPreferences createPreferences();
ITrip createTrip();
ITripInfo createTripInfo();
IVehicle createVehicle();
}

View File

@ -0,0 +1,14 @@
package dst.ass1.jpa.model;
import java.math.BigDecimal;
public interface IMoney {
String getCurrency();
void setCurrency(String currency);
BigDecimal getValue();
void setValue(BigDecimal value);
}

View File

@ -0,0 +1,38 @@
package dst.ass1.jpa.model;
import java.util.Collection;
public interface IOrganization {
Long getId();
void setId(Long id);
String getName();
void setName(String name);
Collection<IOrganization> getParts();
void setParts(Collection<IOrganization> parts);
void addPart(IOrganization part);
Collection<IOrganization> getPartOf();
void setPartOf(Collection<IOrganization> partOf);
void addPartOf(IOrganization partOf);
Collection<IEmployment> getEmployments();
void setEmployments(Collection<IEmployment> employments);
void addEmployment(IEmployment employment);
Collection<IVehicle> getVehicles();
void setVehicles(Collection<IVehicle> vehicles);
void addVehicle(IVehicle vehicle);
}

View File

@ -0,0 +1,20 @@
package dst.ass1.jpa.model;
public interface IPlatformUser {
Long getId();
void setId(Long id);
String getName();
void setName(String name);
String getTel();
void setTel(String tel);
Double getAvgRating();
void setAvgRating(Double avgRating);
}

View File

@ -0,0 +1,16 @@
package dst.ass1.jpa.model;
import java.util.Map;
public interface IPreferences {
Long getId();
void setId(Long id);
Map<String, String> getData();
void setData(Map<String, String> data);
void putData(String key, String value);
}

View File

@ -0,0 +1,32 @@
package dst.ass1.jpa.model;
import java.util.Collection;
public interface IRider extends IPlatformUser {
String getEmail();
void setEmail(String email);
byte[] getPassword();
void setPassword(byte[] password);
String getAccountNo();
void setAccountNo(String accountNo);
String getBankCode();
void setBankCode(String bankCode);
IPreferences getPreferences();
void setPreferences(IPreferences preferences);
Collection<ITrip> getTrips();
void setTrips(Collection<ITrip> trips);
void addTrip(ITrip trip);
}

View File

@ -0,0 +1,49 @@
package dst.ass1.jpa.model;
import java.util.Collection;
import java.util.Date;
public interface ITrip {
Long getId();
void setId(Long id);
Date getCreated();
void setCreated(Date created);
Date getUpdated();
void setUpdated(Date updated);
TripState getState();
void setState(TripState state);
ILocation getPickup();
void setPickup(ILocation pickup);
ILocation getDestination();
void setDestination(ILocation destination);
Collection<ILocation> getStops();
void setStops(Collection<ILocation> stops);
void addStop(ILocation stop);
ITripInfo getTripInfo();
void setTripInfo(ITripInfo tripInfo);
IMatch getMatch();
void setMatch(IMatch match);
IRider getRider();
void setRider(IRider rider);
}

View File

@ -0,0 +1,35 @@
package dst.ass1.jpa.model;
import java.util.Date;
public interface ITripInfo {
Long getId();
void setId(Long id);
Date getCompleted();
void setCompleted(Date date);
Double getDistance();
void setDistance(Double distance);
IMoney getTotal();
void setTotal(IMoney money);
Integer getDriverRating();
void setDriverRating(Integer driverRating);
Integer getRiderRating();
void setRiderRating(Integer riderRating);
ITrip getTrip();
void setTrip(ITrip trip);
}

View File

@ -0,0 +1,20 @@
package dst.ass1.jpa.model;
public interface IVehicle {
Long getId();
void setId(Long id);
String getLicense();
void setLicense(String license);
String getColor();
void setColor(String color);
String getType();
void setType(String type);
}

View File

@ -0,0 +1,5 @@
package dst.ass1.jpa.model;
public enum TripState {
CREATED, QUEUED, MATCHED, APPROACHING, IN_PROGRESS, CANCELLED, COMPLETED
}

View File

@ -0,0 +1,87 @@
package dst.ass1.jpa.model.impl;
import dst.ass1.jpa.model.*;
/**
* Creates new instances of your model implementations.
*/
public class ModelFactory implements IModelFactory {
@Override
public IModelFactory createModelFactory() {
// TODO
return null;
}
@Override
public IDriver createDriver() {
// TODO
return null;
}
@Override
public IEmployment createEmployment() {
// TODO
return null;
}
@Override
public IEmploymentKey createEmploymentKey() {
// TODO
return null;
}
@Override
public ILocation createLocation() {
// TODO
return null;
}
@Override
public IMatch createMatch() {
// TODO
return null;
}
@Override
public IMoney createMoney() {
// TODO
return null;
}
@Override
public IOrganization createOrganization() {
// TODO
return null;
}
@Override
public IRider createRider() {
// TODO
return null;
}
@Override
public IPreferences createPreferences() {
// TODO
return null;
}
@Override
public ITrip createTrip() {
// TODO
return null;
}
@Override
public ITripInfo createTripInfo() {
// TODO
return null;
}
@Override
public IVehicle createVehicle() {
// TODO
return null;
}
}

View File

@ -0,0 +1,121 @@
package dst.ass1.jpa.util;
public final class Constants {
public static final String JPA_PERSISTENCE_UNIT = "dst_pu";
/* TYPES (CLASSES) */
public static final String T_DRIVER = "Driver";
public static final String T_EMPLOYMENT = "Employment";
public static final String T_LOCATION = "Location";
public static final String T_MATCH = "Match";
public static final String T_ORGANIZATION = "Organization";
public static final String T_PREFERENCES = "Preferences";
public static final String T_RIDER = "Rider";
public static final String T_TRIP = "Trip";
public static final String T_TRIP_INFO = "TripInfo";
public static final String T_VEHICLE = "Vehicle";
/* IDs (FOREIGN KEYS) */
public static final String I_DRIVER = "driver_id";
public static final String I_EMPLOYMENT = "employment_id";
public static final String I_LOCATION = "location_id";
public static final String I_MATCH = "match_id";
public static final String I_ORGANIZATION = "organization_id";
public static final String I_ORGANIZATION_PART_OF = "partOfOrganization_id";
public static final String I_ORGANIZATION_PARTS = "partsOrganization_id";
public static final String I_PREFERENCES = "preferences_id";
public static final String I_RIDER = "rider_id";
public static final String I_TRIP = "trip_id";
public static final String I_TRIP_INFO = "tripInfo_id";
public static final String I_VEHICLE = "vehicle_id";
public static final String I_VEHICLES = "vehicles_id";
public static final String I_DESTINATION = "destination_id";
public static final String I_PICKUP = "pickup_id";
public static final String I_STOPS = "stops_id";
/* MEMBER ATTRIBUTES */
public static final String M_DRIVER_TEL = "tel";
public static final String M_DRIVER_ORGANIZATIONS = "organizations";
public static final String M_DRIVER_EMPLOYMENTS = "employments";
public static final String M_DRIVER_VEHICLE = "vehicle";
public static final String M_DRIVER_NAME = "name";
public static final String M_DRIVER_AVG_RATING = "avgRating";
public static final String M_EMPLOYMENT_SINCE = "since";
public static final String M_EMPLOYMENT_ACTIVE = "active";
public static final String M_LOCATION_LOCATION_ID = "locationId";
public static final String M_LOCATION_GEO = "geo";
public static final String M_LOCATION_NAME = "name";
public static final String M_MATCH_DATE = "date";
public static final String M_MATCH_FARE = "fare";
public static final String M_MATCH_TRIP = "trip";
public static final String M_MATCH_VEHICLE = "vehicle";
public static final String M_MATCH_DRIVER = "driver";
public static final String M_ORGANIZATION_NAME = "name";
public static final String M_ORGANIZATION_EMPLOYMENTS = "employments";
public static final String M_ORGANIZATION_PARTS = "parts";
public static final String M_ORGANIZATION_DRIVERS = "drivers";
public static final String M_PREFERENCES_DATA = "data";
public static final String M_RIDER_BANK_CODE = "bankCode";
public static final String M_RIDER_EMAIL = "email";
public static final String M_RIDER_PASSWORD = "password";
public static final String M_RIDER_TEL = "tel";
public static final String M_RIDER_ACCOUNT = "accountNo";
public static final String M_RIDER_PREFERENCES = "preferences";
public static final String M_RIDER_TRIPS = "trips";
public static final String M_RIDER_NAME = "name";
public static final String M_RIDER_AVG_RATING = "avgRating";
public static final String M_TRIP_STOPS = "stops";
public static final String M_TRIP_STATE = "state";
public static final String M_TRIP_CREATED = "created";
public static final String M_TRIP_UPDATED = "updated";
public static final String M_TRIP_PICKUP = "pickup";
public static final String M_TRIP_DESTINATION = "destination";
public static final String M_TRIP_TRIP_INFO = "tripInfo";
public static final String M_TRIP_MATCH = "match";
public static final String M_TRIP_RIDER = "rider";
public static final String M_TRIP_INFO_COMPLETED = "completed";
public static final String M_TRIP_INFO_TOTAL = "total";
public static final String M_TRIP_INFO_DISTANCE = "distance";
public static final String M_TRIP_INFO_TRIP = "trip";
public static final String M_TRIP_INFO_DRIVER_RATING = "driverRating";
public static final String M_TRIP_INFO_RIDER_RATING = "riderRating";
public static final String M_VEHICLE_LICENSE = "license";
public static final String M_VEHICLE_COLOR = "color";
public static final String M_VEHICLE_TYPE = "type";
/* ASSOCIATION NAMES (FOR QUERIES) */
public static final String A_TRIP_INFO = "tripInfo";
public static final String A_TRIP = "trip";
public static final String A_RIDER = "rider";
/* NAMED QUERIES */
public static final String Q_RIDER_BY_EMAIL = "riderByEmail";
public static final String Q_ACTIVE_IN_MULITIPLE_ORGANIZATIONS_DRIVERS = "activeInMultipleOrganizationsDrivers";
public static final String Q_REACHED_LOCATIONS = "reachedLocations";
public static final String Q_SUM_DISTANCE_MOST_RECENT_TRIP = "sumDistanceOfRiderWithMostRecentTrip";
/* JOIN TABLES */
public static final String J_ORGANIZATION_VEHICLE = "organization_vehicle";
public static final String J_ORGANIZATION_PARTS = "organization_parts";
public static final String J_DRIVER_ORGANIZATION = "driver_organization";
public static final String J_PREFERENCES_DATA = "preferences_data";
public static final String J_DRIVER_EMPLOYMENT = "driver_employment";
public static final String J_ORGANIZATION_EMPLOYMENT = "organization_employment";
public static final String J_TRIP_LOCATION = "trip_location";
public static final String J_DRIVER_VEHICLE = "driver_vehicle";
/* MONGODB */
public static final String MONGO_DB_NAME = "dst";
public static final String COLL_LOCATION_DATA = "LocationData";
private Constants() {
// final
}
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
version="2.0">
<!-- TODO -->
</entity-mappings>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
version="2.0">
<!-- TODO -->
</entity-mappings>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="dst_pu">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<mapping-file>META-INF/Trip.xml</mapping-file>
<mapping-file>META-INF/orm.xml</mapping-file>
<properties>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url" value="jdbc:h2:/tmp/database/dst;AUTO_SERVER=TRUE;"/>
<!--<property name="hibernate.connection.username" value=""/>-->
<!--<property name="hibernate.connection.password" value=""/>-->
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.show_sql" value="false"/>
<property name="javax.persistence.validation.mode" value="NONE"/>
<!-- register the sql interceptor -->
<property name="hibernate.session_factory.interceptor" value="dst.ass1.jpa.interceptor.SQLInterceptor"/>
</properties>
</persistence-unit>
</persistence>

View File

@ -0,0 +1,52 @@
package dst.ass1.jpa;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import java.util.ArrayList;
import java.util.List;
/**
* Matcher that finds items in string collections in a case-insensitive way.
*/
public class CaseInsensitiveStringCollectionMatcher extends TypeSafeDiagnosingMatcher<List<String>> {
private final String[] items;
public CaseInsensitiveStringCollectionMatcher(String... items) {
this.items = items;
}
@Factory
public static CaseInsensitiveStringCollectionMatcher hasItems(String... items) {
return new CaseInsensitiveStringCollectionMatcher(items);
}
@Override
protected boolean matchesSafely(List<String> collection, Description description) {
List<String> missing = new ArrayList<>();
for (String item : items) {
if (collection.stream().noneMatch(i -> i.equalsIgnoreCase(item))) {
missing.add(item);
}
}
if (!missing.isEmpty()) {
if (missing.size() == items.length) {
description.appendValueList("was [", ", ", "]", collection);
} else {
description.appendValueList("missing [", ", ", "]", missing)
.appendValueList(" in [", ", ", "]", collection);
}
}
return missing.isEmpty();
}
@Override
public void describeTo(Description description) {
description.appendValueList("collection containing ", " and ", "", items);
}
}

View File

@ -0,0 +1,284 @@
package dst.ass1.jpa;
import org.hibernate.Session;
import org.hibernate.jdbc.ReturningWork;
import javax.persistence.EntityManager;
import javax.persistence.metamodel.Type;
import java.sql.*;
import java.util.*;
import java.util.stream.Collectors;
// DO NOT MODIFY THIS CLASS.
/**
* Contains various methods for accessing the database underlying an EntityManager.
* <p>
* Note that the caller is responsible for dealing with possible exceptions as well as doing the connection handling. A
* connection will not be closed even if a fatal error occurs. However, other SQL resources i.e.,
* {@link Statement Statements} and {@link ResultSet ResultSets} created within the methods, which are not returned to
* the caller, are closed before the method returns.
*/
public class DatabaseGateway {
private final EntityManager em;
public DatabaseGateway(EntityManager em) {
this.em = em;
}
/**
* Returns a list of all table-names for the given database/connection.
*
* @return List of table names
*/
public List<String> getTables() {
return getSession().doReturningWork(new CollectionWork<>("show tables", rs -> rs.getString(1)));
}
/**
* Returns a list of all column names in the given table.
*
* @param tableName the table
* @return a list of column names
*/
public List<String> getColumns(String tableName) {
return getColumnsDefinitions(tableName).stream().map(m -> m.get("COLUMN_NAME")).collect(Collectors.toList());
}
public List<Map<String, String>> getColumnsDefinitions(String tableName) {
String sql = String.format("SELECT * FROM information_schema.columns "
+ "WHERE table_name='%s'", tableName.toUpperCase());
return getSession().doReturningWork(new QueryWork<List<Map<String, String>>>(sql) {
@Override
protected List<Map<String, String>> execute(ResultSet rs) throws SQLException {
List<Map<String, String>> list = new ArrayList<>();
while (rs.next()) {
ResultSetMetaData meta = rs.getMetaData();
Map<String, String> map = new HashMap<>();
for (int i = 1; i <= meta.getColumnCount(); i++) {
String key = meta.getColumnName(i);
String value = rs.getString(key);
map.put(key, value);
}
list.add(map);
}
return list;
}
});
}
/**
* Returns the java types of all managed entity types.
*
* @return a list of java types
*/
public List<Class<?>> getManagedJavaTypes() {
return em.getMetamodel()
.getManagedTypes().stream()
.map(Type::getJavaType)
.collect(Collectors.toList());
}
/**
* Checks if the named table can be accessed via the given EntityManager.
*
* @param tableName the name of the table to find
* @return {@code true} if the database schema contains a table with the given name, {@code false} otherwise
*/
public boolean isTable(final String tableName) {
return getSession().doReturningWork(new QueryWork<Boolean>("show tables") {
@Override
public Boolean execute(ResultSet rs) throws SQLException {
while (rs.next()) {
String tbl = rs.getString(1);
if (tbl.equalsIgnoreCase(tableName)) {
return true;
}
}
return false;
}
});
}
/**
* Checks whether a certain database table contains a column with the given
* name.
*
* @param tableName the name of the table to check
* @param column the name of the column to find
* @return {@code true} if the table contains the column, {@code false} otherwise
*/
public boolean isColumnInTable(String tableName, String column) {
String sql = String.format(
"SELECT * FROM information_schema.columns WHERE table_name='%s' and column_name='%s'",
tableName.toUpperCase(), column.toUpperCase()
);
return getSession().doReturningWork(new HasAtLeastOneEntry(sql));
}
/**
* Checks whether a table contains a column of the given type and length.
*
* @param tableName the table to look for
* @param column the expected column name
* @param type the expected column type
* @param length the expected column length
* @return true if the information schema has at least one such column
*/
public boolean isColumnInTableWithType(String tableName, String column, String type, String length) {
String sql = String.format("SELECT * FROM information_schema.columns "
+ "WHERE table_name='%s' and column_name='%s' and "
+ "type_name='%s' and character_maximum_length='%s'",
tableName.toUpperCase(), column.toUpperCase(), type.toUpperCase(), length);
return getSession().doReturningWork(new HasAtLeastOneEntry(sql));
}
/**
* Checks whether a certain table contains an index for the given column
* name.
*
* @param tableName the name of the table to check
* @param indexName the name of the column the index is created for
* @param nonUnique {@code true} if the index is non unique, {@code false} otherwise
* @return {@code true} if the index exists, {@code false} otherwise
*/
public boolean isIndex(String tableName, String indexName, boolean nonUnique) {
String sql = String.format(
"SELECT * FROM information_schema.indexes WHERE table_name='%s' and column_name='%s' and non_unique='%s'",
tableName.toUpperCase(), indexName.toUpperCase(), nonUnique ? "1" : "0"
);
return getSession().doReturningWork(new HasAtLeastOneEntry(sql));
}
public boolean isComposedIndex(String tableName, String columnName1, String columnName2) {
String indexName1 = getIndexName(tableName, columnName1);
String indexName2 = getIndexName(tableName, columnName2);
return Objects.nonNull(indexName1) && Objects.equals(indexName1, indexName2);
}
private String getIndexName(String tableName, String columnName) {
String sql = String.format(
"SELECT index_name FROM information_schema.indexes WHERE table_name='%s' and column_name='%s'",
tableName.toUpperCase(), columnName.toUpperCase()
);
return getSession().doReturningWork(new QueryWork<String>(sql) {
@Override
protected String execute(ResultSet rs) throws SQLException {
return (rs.next()) ? rs.getString(1) : null;
}
});
}
/**
* Checks whether the given column of a certain table can contain {@code NULL} values.
*
* @param tableName the name of the table to check
* @param columnName the name of the column to check
* @return {@code true} if the column is nullable, {@code false} otherwise
*/
public boolean isNullable(String tableName, String columnName) {
String sql = String.format(
"SELECT * FROM information_schema.columns " +
"WHERE table_name='%s' and column_name='%s' and IS_NULLABLE=true",
tableName.toUpperCase(), columnName.toUpperCase()
);
return getSession().doReturningWork(new HasAtLeastOneEntry(sql));
}
/**
* Deletes all data from all tables that can be accessed via the given EntityManager.
*/
public void truncateTables() {
List<String> tables = getTables();
tables.removeIf(t -> t.toLowerCase().startsWith("hibernate"));
getSession().doWork(connection -> {
try (Statement stmt = connection.createStatement()) {
stmt.addBatch("SET FOREIGN_KEY_CHECKS=0");
for (String table : tables) {
stmt.addBatch("TRUNCATE TABLE " + table);
}
stmt.addBatch("SET FOREIGN_KEY_CHECKS=1");
stmt.executeBatch();
}
});
}
public Session getSession() {
return em.unwrap(Session.class);
}
public interface StatementWork<T> extends ReturningWork<T> {
default T execute(Connection connection) throws SQLException {
try (Statement stmt = connection.createStatement()) {
return execute(stmt);
}
}
T execute(Statement stmt) throws SQLException;
}
@FunctionalInterface
public interface CheckedFunction<T, R, E extends Exception> {
R apply(T t) throws E;
}
public static abstract class QueryWork<T> implements StatementWork<T> {
private final String sql;
public QueryWork(String sql) {
this.sql = sql;
}
@Override
public T execute(Statement stmt) throws SQLException {
try (ResultSet rs = stmt.executeQuery(sql)) {
return execute(rs);
}
}
protected abstract T execute(ResultSet rs) throws SQLException;
}
public static class HasAtLeastOneEntry extends QueryWork<Boolean> {
public HasAtLeastOneEntry(String sql) {
super(sql);
}
@Override
protected Boolean execute(ResultSet rs) throws SQLException {
return rs.next();
}
}
public static class CollectionWork<T> extends QueryWork<List<T>> {
private final CheckedFunction<ResultSet, T, SQLException> extractor;
public CollectionWork(String sql, CheckedFunction<ResultSet, T, SQLException> extractor) {
super(sql);
this.extractor = extractor;
}
@Override
protected List<T> execute(ResultSet rs) throws SQLException {
List<T> list = new ArrayList<>();
while (rs.next()) {
list.add(extractor.apply(rs));
}
return list;
}
}
}

View File

@ -0,0 +1,21 @@
package dst.ass1.jpa;
import dst.ass1.jpa.model.IModelFactory;
import javax.persistence.EntityManager;
// DO NOT MODIFY THIS CLASS.
/**
* The ITestData interface is used by the {@link ORMService} to insert test data before each test run. You can pass
* custom implementation of {@link ITestData} to the constructor of {@link ORMService} to create your own test fixture.
*/
public interface ITestData {
/**
* Creates test data using the model factory and inserts them into the entity manager.
*
* @param modelFactory the model factory
* @param em the entity manager
*/
void insert(IModelFactory modelFactory, EntityManager em);
}

View File

@ -0,0 +1,172 @@
package dst.ass1.jpa;
import dst.ass1.jpa.dao.IDAOFactory;
import dst.ass1.jpa.dao.impl.DAOFactory;
import dst.ass1.jpa.model.IModelFactory;
import dst.ass1.jpa.model.impl.ModelFactory;
import dst.ass1.jpa.util.Constants;
import org.junit.rules.ExternalResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
// DO NOT MODIFY THIS CLASS.
/**
* The ORMService class is used as a JUnit rule that, before each test run,
* a) creates an entity manager factory from the persistence unit referenced in {@link Constants#JPA_PERSISTENCE_UNIT},
* b) creates an entity manager using the factory,
* c) creates dao and model factory instances, and
* d) creates a database gateway for the entity manager.
* <p>
* It provides methods to access these services, and it closes the entity manager and corresponding factory after each
* test run. If you pass an {@link ITestData} instance to the constructor, the {@link ORMService} will also insert test
* data via a transaction before each run, and truncate tables after each run.
*/
public class ORMService extends ExternalResource {
private static final Logger LOG = LoggerFactory.getLogger(ORMService.class);
private static EntityManagerFactory emf;
private EntityManager em;
private DatabaseGateway databaseGateway;
private IModelFactory modelFactory;
private IDAOFactory daoFactory;
private ITestData testData;
private boolean insertTestData;
private boolean truncateTables;
/**
* Creates a new ORMService. By default, the ORMService rule only creates the database connection and other
* ORM facilities. If you want to also insert a test fixture, use {@link #ORMService(ITestData)}.
*/
public ORMService() {
this(null, false, false);
}
/**
* Creates a new ORMService that also inserts the given {@link ITestData} before each run and truncates the tables
* afterwards.
*
* @param testData the test data to insert
*/
public ORMService(ITestData testData) {
this(testData, true, true);
}
public ORMService(ITestData testData, boolean insertTestData, boolean truncateTables) {
this.testData = testData;
this.insertTestData = insertTestData;
this.truncateTables = truncateTables;
}
private static EntityManagerFactory createEntityManagerFactory() {
return Persistence.createEntityManagerFactory(Constants.JPA_PERSISTENCE_UNIT);
}
public EntityManager getEntityManager() {
return em;
}
public EntityManager createEntityManager() {
return emf.createEntityManager();
}
public IModelFactory getModelFactory() {
return modelFactory;
}
public IDAOFactory getDaoFactory() {
return daoFactory;
}
public DatabaseGateway getDatabaseGateway() {
return databaseGateway;
}
/**
* Alias for {@link #getEntityManager()}.
*
* @return an entity manager
*/
public EntityManager em() {
return getEntityManager();
}
@Override
protected void before() throws Throwable {
LOG.debug("Creating EntityManagerFactory");
emf = createEntityManagerFactory();
LOG.debug("Creating EntityManager");
em = emf.createEntityManager();
databaseGateway = new DatabaseGateway(em);
LOG.debug("Initializing factories");
// initialize factories
modelFactory = new ModelFactory();
daoFactory = new DAOFactory(em);
if (testData != null && insertTestData) {
insertTestData(testData);
}
}
@Override
protected void after() {
if (truncateTables) {
truncateTables();
}
try {
LOG.debug("Closing EntityManager");
em.close();
} catch (Exception e) {
LOG.error("Error while closing entity manager", e);
}
try {
LOG.debug("Closing EntityManagerFactory");
emf.close();
} catch (Exception e) {
LOG.error("Error while closing entity manager factory", e);
}
}
protected void insertTestData(ITestData data) {
EntityTransaction tx = getEntityManager().getTransaction();
tx.begin();
try {
data.insert(getModelFactory(), getEntityManager());
tx.commit();
} catch (Exception e) {
try {
if (tx.isActive()) {
tx.rollback();
}
} catch (Exception rollbackException) {
LOG.error("Error while rolling back transaction after exception", rollbackException);
} finally {
throw new IllegalStateException("Couldn't insert fixture. Can't proceed with tests", e); // rethrow original exception
}
}
}
protected void truncateTables() {
try {
LOG.debug("Truncating database tables");
getDatabaseGateway().truncateTables();
} catch (Exception e) {
LOG.error("Error while trying to truncate tables after test", e);
}
}
}

View File

@ -0,0 +1,69 @@
package dst.ass1.jpa.examples;
import dst.ass1.jpa.ITestData;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.dao.IVehicleDAO;
import dst.ass1.jpa.model.IModelFactory;
import dst.ass1.jpa.model.IVehicle;
import org.junit.Rule;
import org.junit.Test;
import javax.persistence.EntityManager;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* This examples shows how you can write your own tests with custom fixtures that are injected it into the
* {@link ORMService} rule. Using rules instead of abstract tests is considered good practice as it follows the
* principle of composition over inheritance.
*/
public class ExampleTestWithCustomTestData {
@Rule
public ORMService orm = new ORMService(new MyTestData());
@Test
public void vehicleDAO_findAll_returnsCorrectValues() throws Exception {
IVehicleDAO vehicleDAO = orm.getDaoFactory().createVehicleDAO();
List<IVehicle> all = vehicleDAO.findAll();
assertThat(all.isEmpty(), is(false));
assertThat(all.size(), is(2));
System.out.println(all);
}
@Test
public void vehicleDAO_findById_returnsCorrectValue() throws Exception {
IVehicleDAO vehicleDAO = orm.getDaoFactory().createVehicleDAO();
IVehicle actual = vehicleDAO.findById(1L);
assertThat(actual.getColor(), is("red"));
}
public static class MyTestData implements ITestData {
@Override
public void insert(IModelFactory modelFactory, EntityManager em) {
IVehicle vehicle1 = modelFactory.createVehicle();
IVehicle vehicle2 = modelFactory.createVehicle();
vehicle1.setColor("red");
vehicle1.setLicense("license1");
vehicle1.setType("type_1");
vehicle2.setColor("blue");
vehicle2.setLicense("license2");
vehicle2.setType("type_2");
em.persist(vehicle1);
em.persist(vehicle2);
em.flush(); // transaction is done through the ORMTestFixture
}
}
}

View File

@ -0,0 +1,70 @@
package dst.ass1.jpa.examples;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.dao.IDAOFactory;
import dst.ass1.jpa.dao.IVehicleDAO;
import dst.ass1.jpa.model.IModelFactory;
import dst.ass1.jpa.model.IVehicle;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import javax.persistence.EntityManager;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* This test has no test fixture and dependencies between tests. This is possible by declaring {@link ORMService} as a
* static class-level rule via {@link ClassRule}.
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ExampleTestWithDependencies {
@ClassRule
public static ORMService orm = new ORMService();
@Test
public void t01_insert() throws Exception {
EntityManager em = orm.getEntityManager();
IModelFactory modelFactory = orm.getModelFactory();
IVehicle vehicle1 = modelFactory.createVehicle();
IVehicle vehicle2 = modelFactory.createVehicle();
vehicle1.setColor("red");
vehicle1.setLicense("license1");
vehicle1.setType("type_1");
vehicle2.setColor("blue");
vehicle2.setLicense("license2");
vehicle2.setType("type_2");
em.persist(vehicle1);
em.persist(vehicle2);
em.getTransaction().begin();
em.flush();
em.getTransaction().commit();
assertThat(vehicle1.getId(), notNullValue());
assertThat(vehicle2.getId(), notNullValue());
}
@Test
public void t02_query() throws Exception {
IDAOFactory daoFactory = orm.getDaoFactory();
IVehicleDAO vehicleDAO = daoFactory.createVehicleDAO();
List<IVehicle> all = vehicleDAO.findAll();
assertThat(all.isEmpty(), is(false));
assertThat(all.size(), is(2));
System.out.println(all);
}
}

View File

@ -0,0 +1,6 @@
/**
* This package contains a couple of examples of how you can use JUnit and our simple ORM test framework to create your
* own tests.
*/
package dst.ass1.jpa.examples;

View File

@ -0,0 +1,103 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.ITestData;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.dao.*;
import dst.ass1.jpa.model.*;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
import org.junit.runners.MethodSorters;
import javax.persistence.EntityTransaction;
import java.util.List;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.object.IsCompatibleType.typeCompatibleWith;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* Tests the basic setup of the model and dao factory (makes sure they don't return null), and also tests whether all
* relevant entities have been mapped at all and test data can be inserted.
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class Ass1_1_1_00Test {
@ClassRule
public static ORMService orm = new ORMService();
@Rule
public ErrorCollector err = new ErrorCollector();
@Test
public void test01_modelFactoryReturnsThings() {
IModelFactory modelFactory = orm.getModelFactory();
err.checkThat(modelFactory.createDriver(), isA(IDriver.class));
err.checkThat(modelFactory.createEmployment(), isA(IEmployment.class));
err.checkThat(modelFactory.createEmploymentKey(), isA(IEmploymentKey.class));
err.checkThat(modelFactory.createLocation(), isA(ILocation.class));
err.checkThat(modelFactory.createMatch(), isA(IMatch.class));
err.checkThat(modelFactory.createMoney(), isA(IMoney.class));
err.checkThat(modelFactory.createOrganization(), isA(IOrganization.class));
err.checkThat(modelFactory.createRider(), isA(IRider.class));
err.checkThat(modelFactory.createPreferences(), isA(IPreferences.class));
err.checkThat(modelFactory.createTrip(), isA(ITrip.class));
err.checkThat(modelFactory.createTripInfo(), isA(ITripInfo.class));
err.checkThat(modelFactory.createVehicle(), isA(IVehicle.class));
}
@Test
public void test02_daoFactoryReturnsThings() {
IDAOFactory daoFactory = orm.getDaoFactory();
err.checkThat(daoFactory.createDriverDAO(), isA(IDriverDAO.class));
err.checkThat(daoFactory.createEmploymentDAO(), isA(IEmploymentDAO.class));
err.checkThat(daoFactory.createLocationDAO(), isA(ILocationDAO.class));
err.checkThat(daoFactory.createMatchDAO(), isA(IMatchDAO.class));
err.checkThat(daoFactory.createOrganizationDAO(), isA(IOrganizationDAO.class));
err.checkThat(daoFactory.createRiderDAO(), isA(IRiderDAO.class));
err.checkThat(daoFactory.createTripDAO(), isA(ITripDAO.class));
err.checkThat(daoFactory.createTripInfoDAO(), isA(ITripInfoDAO.class));
err.checkThat(daoFactory.createVehicleDAO(), isA(IVehicleDAO.class));
}
@Test
public void test03_entityTypesManagedCorrectly() throws Exception {
List<Class<?>> types = orm.getDatabaseGateway().getManagedJavaTypes();
assertThat("No managed types found", types.isEmpty(), is(false));
System.out.println("Managed types: " + types);
err.checkThat(types, hasItem(typeCompatibleWith(IDriver.class)));
err.checkThat(types, hasItem(typeCompatibleWith(IEmployment.class)));
err.checkThat(types, hasItem(typeCompatibleWith(IEmploymentKey.class)));
err.checkThat(types, hasItem(typeCompatibleWith(ILocation.class)));
err.checkThat(types, hasItem(typeCompatibleWith(IMoney.class)));
err.checkThat(types, hasItem(typeCompatibleWith(IOrganization.class)));
err.checkThat(types, hasItem(typeCompatibleWith(IRider.class)));
err.checkThat(types, hasItem(typeCompatibleWith(IPreferences.class)));
err.checkThat(types, hasItem(typeCompatibleWith(ITrip.class)));
err.checkThat(types, hasItem(typeCompatibleWith(ITripInfo.class)));
err.checkThat(types, hasItem(typeCompatibleWith(IVehicle.class)));
}
@Test
public void test04_canInsertTestFixture() throws Exception {
ITestData testData = new TestData();
EntityTransaction tx = orm.em().getTransaction();
tx.begin();
try {
testData.insert(orm.getModelFactory(), orm.em());
} catch (Exception e) {
throw new AssertionError("Exception while inserting test fixture.", e);
} finally {
tx.rollback();
}
}
}

View File

@ -0,0 +1,179 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.DatabaseGateway;
import dst.ass1.jpa.ORMService;
import org.junit.*;
import org.junit.rules.ErrorCollector;
import org.junit.runners.MethodSorters;
import static dst.ass1.jpa.CaseInsensitiveStringCollectionMatcher.hasItems;
import static dst.ass1.jpa.util.Constants.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
/**
* Tests the basic object-relational mapping by examining the created database tables and constraints.
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class Ass1_1_1_01Test {
@ClassRule
public static ORMService orm = new ORMService();
@Rule
public ErrorCollector err = new ErrorCollector();
private DatabaseGateway db;
@Before
public void setUp() throws Exception {
db = orm.getDatabaseGateway();
}
@Test
public void printTables() throws Exception {
// not a test, just some systout output that may help you to gain insight into the created database schema
for (String table : db.getTables()) {
System.out.printf("%-30s %s%n", table, db.getColumns(table));
}
}
@Test
public void testBasicTablesJdbc() throws Exception {
// checks that all basic tables exist
err.checkThat(db.getTables(), hasItems(
T_RIDER,
T_TRIP,
T_LOCATION,
T_TRIP_INFO,
T_DRIVER,
T_EMPLOYMENT,
T_ORGANIZATION,
T_VEHICLE,
T_MATCH,
T_PREFERENCES
));
}
@Test
public void testRelation01Jdbc() throws Exception {
// driver -> vehicle
err.checkThat(db.getColumns(T_DRIVER), hasItems(I_VEHICLE));
err.checkThat(db.isNullable(T_DRIVER, I_VEHICLE), is(false));
err.checkThat(db.getTables(), not(hasItems(J_DRIVER_VEHICLE)));
}
@Test
public void testRelation02Jdbc() throws Exception {
// rider <-> trip
err.checkThat(db.getColumns(T_TRIP), hasItems(I_RIDER));
}
@Test
public void testRelation03Jdbc() throws Exception {
// driver <- employment -> organization
err.checkThat(db.getColumns(T_EMPLOYMENT), hasItems(
I_DRIVER,
I_ORGANIZATION
));
}
@Test
public void testRelation04Jdbc() throws Exception {
// trip <-> match -> vehicle
// |
// v
// driver
err.checkThat(db.getColumns(T_MATCH), hasItems(
I_DRIVER,
I_TRIP,
I_VEHICLE
));
err.checkThat(db.getColumns(T_DRIVER), not(hasItems(I_MATCH)));
err.checkThat(db.getColumns(T_TRIP), not(hasItems(I_MATCH)));
err.checkThat(db.getColumns(T_VEHICLE), not(hasItems(I_MATCH)));
err.checkThat(db.getColumns(T_MATCH), hasItems(I_TRIP));
}
@Test
public void testRelation05Jdbc() throws Exception {
// organization <-> organization
err.checkThat("join table should be explicitly renamed!", db.getTables(), not(hasItems(
T_ORGANIZATION + "_" + T_ORGANIZATION
)));
err.checkThat(db.getTables(), hasItems(
J_ORGANIZATION_PARTS
));
err.checkThat(db.getColumns(J_ORGANIZATION_PARTS), hasItems(
I_ORGANIZATION_PARTS,
I_ORGANIZATION_PART_OF
));
}
@Test
public void testRelation06Jdbc() throws Exception {
// trip -> location (stops)
err.checkThat(db.getTables(), hasItems(J_TRIP_LOCATION));
err.checkThat(db.getColumns(J_TRIP_LOCATION), hasItems(I_TRIP));
err.checkThat(db.getColumns(J_TRIP_LOCATION), hasItems(I_STOPS));
}
@Test
public void testRelation07Jdbc() throws Exception {
// trip -> location (pickup)
err.checkThat(db.getColumns(T_TRIP), hasItems(I_PICKUP));
err.checkThat(db.isIndex(T_TRIP, I_PICKUP, true), is(true));
err.checkThat(db.isNullable(T_TRIP, I_PICKUP), is(false));
}
@Test
public void testRelation08Jdbc() throws Exception {
// trip -> location (destination)
err.checkThat(db.getColumns(T_TRIP), hasItems(I_DESTINATION));
err.checkThat(db.isIndex(T_TRIP, I_DESTINATION, true), is(true));
err.checkThat(db.isNullable(T_TRIP, I_DESTINATION), is(false));
}
@Test
public void testRelation09Jdbc() throws Exception {
// trip <-> tripinfo
err.checkThat(db.getColumns(T_TRIP_INFO), hasItems(I_TRIP));
err.checkThat(db.isNullable(T_TRIP_INFO, I_TRIP), is(false));
}
@Test
public void testRelation10Jdbc() throws Exception {
// organization -> vehicle
err.checkThat(db.getTables(), hasItems(J_ORGANIZATION_VEHICLE));
err.checkThat(db.getColumns(J_ORGANIZATION_VEHICLE), hasItems(
I_ORGANIZATION,
I_VEHICLES
));
}
@Test
public void testRelation11Jdbc() throws Exception {
// rider -> preferences
err.checkThat(db.getColumns(T_RIDER), hasItems(I_PREFERENCES));
err.checkThat(db.isNullable(T_RIDER, I_PREFERENCES), is(false));
err.checkThat(db.getColumns(T_PREFERENCES), not(hasItems(I_RIDER)));
}
@Test
public void testColumnType01Jdbc() {
err.checkThat(db.isColumnInTableWithType(T_RIDER, M_RIDER_PASSWORD, "VARBINARY", "20"), is(true));
}
}

View File

@ -0,0 +1,30 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.util.Constants;
import org.junit.Rule;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
/**
* Tests the IVehicle license unique constraint.
*/
public class Ass1_1_1_02Test {
@Rule
public ORMService orm = new ORMService();
@Test
public void testConstraint() {
new UniqueConstraintTester<>(() -> orm.getModelFactory().createVehicle(), e -> e.setLicense("uniquevalue"))
.run(orm.getEntityManager());
}
@Test
public void testConstraintJdbc() {
assertTrue(orm.getDatabaseGateway().isIndex(Constants.T_VEHICLE, Constants.M_VEHICLE_LICENSE, false));
assertTrue(orm.getDatabaseGateway().isNullable(Constants.T_VEHICLE, Constants.M_VEHICLE_LICENSE));
}
}

View File

@ -0,0 +1,48 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.model.IPreferences;
import dst.ass1.jpa.model.IRider;
import dst.ass1.jpa.util.Constants;
import org.hibernate.PropertyValueException;
import org.junit.Rule;
import org.junit.Test;
import javax.persistence.PersistenceException;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.*;
/**
* Tests the IRider tel not null constraint.
*/
public class Ass1_1_1_03Test {
@Rule
public ORMService orm = new ORMService();
@Test
public void testConstraint() {
IRider e1 = orm.getModelFactory().createRider();
e1.setEmail("email@example.com");
e1.setTel(null);
IPreferences preferences = orm.getModelFactory().createPreferences();
e1.setPreferences(preferences);
var e = assertThrows(PersistenceException.class, () -> {
orm.em().getTransaction().begin();
orm.em().persist(preferences);
orm.em().persist(e1);
orm.em().flush();
});
assertThat(e.getMessage(), containsString("not-null property"));
assertThat(e.getCause(), is(instanceOf(PropertyValueException.class)));
}
@Test
public void testConstraintJdbc() {
assertFalse(orm.getDatabaseGateway().isNullable(Constants.T_RIDER, Constants.M_RIDER_TEL));
}
}

View File

@ -0,0 +1,43 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.model.IDriver;
import dst.ass1.jpa.util.Constants;
import org.hibernate.PropertyValueException;
import org.junit.Rule;
import org.junit.Test;
import javax.persistence.PersistenceException;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
/**
* Tests the IDriver tel not null constraint.
*/
public class Ass1_1_1_04Test {
@Rule
public ORMService orm = new ORMService();
@Test
public void testConstraint() {
IDriver e1 = orm.getModelFactory().createDriver();
e1.setTel(null);
var e = assertThrows(PersistenceException.class, () -> {
orm.em().getTransaction().begin();
orm.em().persist(e1);
orm.em().flush();
});
assertThat(e.getMessage(), containsString("not-null property"));
assertThat(e.getCause(), is(instanceOf(PropertyValueException.class)));
}
@Test
public void testConstraintJdbc() {
assertFalse(orm.getDatabaseGateway().isNullable(Constants.T_DRIVER, Constants.M_DRIVER_TEL));
}
}

View File

@ -0,0 +1,52 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.model.IMoney;
import org.junit.Rule;
import org.junit.Test;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Type;
import java.math.BigDecimal;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
/**
* Tests if IMoney is implemented correctly.
*/
public class Ass1_1_1_05Test {
@Rule
public ORMService orm = new ORMService();
@Test
public void moneyEntityCannotBePersisted() {
IMoney money = orm.getModelFactory().createMoney();
assertNotNull(money);
money.setValue(BigDecimal.TEN);
money.setCurrency("EURO");
assertThrows(IllegalArgumentException.class, () -> {
orm.getEntityManager().persist(money);
});
}
@Test
public void moneyIsEmbeddableType() {
IMoney money = orm.getModelFactory().createMoney();
assertNotNull(money);
ManagedType<?> type = orm.getEntityManager().getMetamodel().managedType(money.getClass());
assertNotNull(type);
assertThat(type.getPersistenceType(), is(Type.PersistenceType.EMBEDDABLE));
}
@Test
public void moneyHasNoTable() throws Exception {
assertFalse(orm.getDatabaseGateway().isTable("MONEY"));
}
}

View File

@ -0,0 +1,58 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.model.IPreferences;
import dst.ass1.jpa.util.Constants;
import org.junit.Rule;
import org.junit.Test;
import javax.persistence.EntityManager;
import java.util.Map;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* Tests that IPreferences is persisted correctly.
*/
public class Ass1_1_1_06Test {
@Rule
public ORMService orm = new ORMService();
@Test
public void testPreferencesMap() {
IPreferences pref1 = orm.getModelFactory().createPreferences();
pref1.putData("key1", "value1");
pref1.putData("key2", "value2");
EntityManager em = orm.getEntityManager();
em.getTransaction().begin();
em.persist(pref1);
em.flush();
em.getTransaction().commit();
EntityManager em2 = orm.createEntityManager();
IPreferences md2 = em2.find(pref1.getClass(), pref1.getId());
Map<String, String> map = md2.getData();
assertThat(map.size(), is(2));
assertThat(map.keySet(), hasItems("key1", "key2"));
assertThat(map.get("key1"), is("value1"));
assertThat(map.get("key2"), is("value2"));
}
@Test
public void testPreferencesMapJdbc() {
assertTrue(orm.getDatabaseGateway().isTable(Constants.T_PREFERENCES));
assertTrue(orm.getDatabaseGateway().isTable(Constants.J_PREFERENCES_DATA));
assertTrue(orm.getDatabaseGateway().isColumnInTable(Constants.J_PREFERENCES_DATA, Constants.I_PREFERENCES));
assertTrue(orm.getDatabaseGateway().isColumnInTable(Constants.J_PREFERENCES_DATA, Constants.M_PREFERENCES_DATA + "_KEY"));
}
}

View File

@ -0,0 +1,91 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.model.IPreferences;
import dst.ass1.jpa.model.IRider;
import dst.ass1.jpa.model.ITrip;
import org.hibernate.PropertyValueException;
import org.hibernate.exception.ConstraintViolationException;
import org.junit.Test;
import javax.persistence.PersistenceException;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
/**
* Tests if the IRider and IPreferences relation is implemented correctly.
*/
public class Ass1_1_1_07Test extends Ass1_TestBase {
@Test
public void testPreferencesAssociation() {
IRider rider1 = daoFactory.createRiderDAO().findById(testData.rider1Id);
assertNotNull(rider1);
assertEquals(testData.preferences1Id, rider1.getPreferences().getId());
IRider rider2 = daoFactory.createRiderDAO().findById(testData.rider2Id);
assertNotNull(rider2);
assertEquals(testData.preferences2Id, rider2.getPreferences().getId());
}
@Test
public void testPreferencesNonOptionalConstraint() {
IRider rider1 = daoFactory.createRiderDAO().findById(testData.rider1Id);
assertNotNull(rider1);
rider1.setPreferences(null);
var e = assertThrows(PersistenceException.class, () -> {
em.getTransaction().begin();
em.persist(rider1);
em.flush();
});
assertThat(e.getMessage(), containsString("not-null property"));
assertThat(e.getCause(), is(instanceOf(PropertyValueException.class)));
}
@Test
public void testPreferencesUniqueConstraint() throws Exception {
IRider rider1 = daoFactory.createRiderDAO().findById(testData.rider1Id);
IPreferences preferences1 = rider1.getPreferences();
IRider rider5 = modelFactory.createRider();
rider5.setEmail("email@example.com");
rider5.setName("rider5");
rider5.setTel("tel");
rider5.setPreferences(preferences1);
em.getTransaction().begin();
var missingException = "Persisting the same metadata object with a different course should result in a constraint violation";
var e = assertThrows(missingException, PersistenceException.class, () -> {
em.persist(rider5);
em.flush();
});
assertThat(missingException, e.getCause(), is(instanceOf(ConstraintViolationException.class)));
}
@Test
public void testRiderPreferencesDeleteCascade() throws Exception {
IRider rider = daoFactory.createRiderDAO().findById(testData.rider4Id);
Long preferencesId = rider.getPreferences().getId();
em.getTransaction().begin();
try {
for (ITrip trip : rider.getTrips()) {
trip.setRider(null);
}
em.remove(rider);
em.flush();
} catch (PersistenceException e) {
throw new AssertionError("Removing a rider should not result in a PersistenceException", e);
}
em.getTransaction().commit();
em.getTransaction().begin();
IPreferences preferences = em.find(modelFactory.createPreferences().getClass(), preferencesId);
assertNull("Expected preferences to be null after associated rider was deleted", preferences);
}
}

View File

@ -0,0 +1,49 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.model.IRider;
import dst.ass1.jpa.model.ITrip;
import dst.ass1.jpa.model.TripState;
import org.junit.Test;
import java.util.List;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
/**
* Tests the 1-N association between ITrip and IRider (its creator).
*/
public class Ass1_1_1_08Test extends Ass1_TestBase {
@Test
public void testTripRiderAssociation() {
IRider rider1 = daoFactory.createRiderDAO().findById(testData.rider4Id);
assertNotNull(rider1);
assertNotNull(rider1.getTrips());
List<Long> tripIds = map(rider1.getTrips(), ITrip::getId);
assertEquals(1, tripIds.size());
assertThat(tripIds, hasItem(testData.trip6Id));
ITrip trip1 = daoFactory.createTripDAO().findById(testData.trip6Id);
ITrip trip2 = daoFactory.createTripDAO().findById(testData.trip1Id);
assertNotNull(trip1);
assertNotNull(trip2);
assertEquals(testData.rider4Id, trip1.getRider().getId());
assertEquals(testData.rider1Id, trip2.getRider().getId());
}
@Test
public void testTripStatus() {
ITrip trip1 = daoFactory.createTripDAO().findById(testData.trip1Id);
assertEquals(TripState.COMPLETED, trip1.getState());
ITrip trip2 = daoFactory.createTripDAO().findById(testData.trip6Id);
assertEquals(TripState.CREATED, trip2.getState());
}
}

View File

@ -0,0 +1,84 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.dao.IOrganizationDAO;
import dst.ass1.jpa.dao.IVehicleDAO;
import dst.ass1.jpa.dao.impl.DAOFactory;
import dst.ass1.jpa.model.IOrganization;
import dst.ass1.jpa.model.IVehicle;
import org.junit.Test;
import javax.persistence.EntityManager;
import java.util.List;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
/**
* Tests the association between IOrganization and IVehicle.
*/
public class Ass1_1_1_09Test extends Ass1_TestBase {
@Test
public void testOrganizationVehicleAssociation() {
EntityManager em = orm.createEntityManager();
DAOFactory daoFactory = new DAOFactory(em);
IOrganizationDAO organizationDAO = daoFactory.createOrganizationDAO();
IVehicleDAO vehicleDAO = daoFactory.createVehicleDAO();
List<IVehicle> vehicles = vehicleDAO.findAll();
assertNotNull(vehicles);
assertEquals(4, vehicles.size());
IVehicle vehicle1 = vehicleDAO.findById(testData.vehicle1Id);
IVehicle vehicle2 = vehicleDAO.findById(testData.vehicle2Id);
IVehicle vehicle3 = vehicleDAO.findById(testData.vehicle3Id);
IVehicle vehicle4 = vehicleDAO.findById(testData.vehicle4Id);
assertEquals(testData.vehicle1Id, vehicle1.getId());
assertEquals(testData.vehicle2Id, vehicle2.getId());
assertEquals(testData.vehicle3Id, vehicle3.getId());
assertEquals(testData.vehicle4Id, vehicle4.getId());
List<IOrganization> organizations = organizationDAO.findAll();
assertNotNull(organizations);
assertEquals(5, organizations.size());
IOrganization organization1 = organizationDAO.findById(testData.organization1Id);
IOrganization organization2 = organizationDAO.findById(testData.organization2Id);
IOrganization organization3 = organizationDAO.findById(testData.organization3Id);
IOrganization organization4 = organizationDAO.findById(testData.organization4Id);
IOrganization organization5 = organizationDAO.findById(testData.organization5Id);
assertEquals(testData.organization1Id, organization1.getId());
assertNotNull(organization1.getVehicles());
assertThat(organization1.getVehicles().size(), is(3));
List<Long> vehicleIds1 = map(organization1.getVehicles(), IVehicle::getId);
assertThat(vehicleIds1, hasItems(testData.vehicle1Id, testData.vehicle2Id, testData.vehicle3Id));
assertEquals(testData.organization2Id, organization2.getId());
assertNotNull(organization2.getVehicles());
assertThat(organization2.getVehicles().size(), is(1));
List<Long> vehicleIds2 = map(organization2.getVehicles(), IVehicle::getId);
assertThat(vehicleIds2, hasItems(testData.vehicle4Id));
assertEquals(testData.organization3Id, organization3.getId());
assertNotNull(organization3.getVehicles());
assertThat(organization3.getVehicles().size(), is(0));
assertEquals(testData.organization4Id, organization4.getId());
assertNotNull(organization4.getVehicles());
assertThat(organization4.getVehicles().size(), is(0));
assertEquals(testData.organization5Id, organization5.getId());
assertNotNull(organization5.getVehicles());
assertThat(organization5.getVehicles().size(), is(0));
}
}

View File

@ -0,0 +1,107 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.dao.IOrganizationDAO;
import dst.ass1.jpa.dao.impl.DAOFactory;
import dst.ass1.jpa.model.IOrganization;
import dst.ass1.jpa.util.Constants;
import org.hibernate.Session;
import org.junit.Test;
import javax.persistence.EntityManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.core.IsCollectionContaining.hasItem;
import static org.hamcrest.core.IsCollectionContaining.hasItems;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
/**
* Tests the self reference of IOrganization.
*/
public class Ass1_1_1_10Test extends Ass1_TestBase {
@Test
public void testOrganizationSelfAssociation() {
EntityManager em = orm.createEntityManager();
IOrganizationDAO dao = new DAOFactory(em).createOrganizationDAO();
IOrganization organization1 = dao.findById(testData.organization1Id);
IOrganization organization2 = dao.findById(testData.organization2Id);
IOrganization organization3 = dao.findById(testData.organization3Id);
IOrganization organization4 = dao.findById(testData.organization4Id);
IOrganization organization5 = dao.findById(testData.organization5Id);
assertNotNull(organization1.getParts());
assertNotNull(organization1.getPartOf());
assertNotNull(organization2.getParts());
assertNotNull(organization2.getPartOf());
assertNotNull(organization3.getParts());
assertNotNull(organization3.getPartOf());
assertNotNull(organization4.getParts());
assertNotNull(organization4.getPartOf());
assertNotNull(organization5.getParts());
assertNotNull(organization5.getPartOf());
List<Long> organization1Parts = map(organization1.getParts(), IOrganization::getId);
List<Long> organization1PartOf = map(organization1.getPartOf(), IOrganization::getId);
List<Long> organization2Parts = map(organization2.getParts(), IOrganization::getId);
List<Long> organization2PartOf = map(organization2.getPartOf(), IOrganization::getId);
List<Long> organization3Parts = map(organization3.getParts(), IOrganization::getId);
List<Long> organization3PartOf = map(organization3.getPartOf(), IOrganization::getId);
List<Long> organization4Parts = map(organization4.getParts(), IOrganization::getId);
List<Long> organization4PartOf = map(organization4.getPartOf(), IOrganization::getId);
List<Long> organization5Parts = map(organization5.getParts(), IOrganization::getId);
List<Long> organization5PartOf = map(organization5.getPartOf(), IOrganization::getId);
assertThat(organization1Parts, hasItems(testData.organization4Id, testData.organization5Id));
assertThat(organization1PartOf, hasItem(testData.organization2Id));
assertThat(organization2Parts, hasItem(testData.organization1Id));
assertThat(organization2PartOf, hasItems(testData.organization4Id));
assertThat(organization3Parts.size(), is(0));
assertThat(organization3PartOf.size(), is(0));
assertThat(organization4Parts, hasItems(testData.organization2Id));
assertThat(organization4PartOf, hasItems(testData.organization1Id));
assertThat(organization5Parts.size(), is(0));
assertThat(organization5PartOf, hasItems(testData.organization1Id));
}
@Test
public void testOrganizationSelfAssociationJdbc() {
String sql = "SELECT " + Constants.I_ORGANIZATION_PARTS + ", " + Constants.I_ORGANIZATION_PART_OF +
" FROM " + Constants.J_ORGANIZATION_PARTS +
" ORDER BY " + Constants.I_ORGANIZATION_PARTS + ", " + Constants.I_ORGANIZATION_PART_OF;
em.unwrap(Session.class).doWork(connection -> {
try (Statement stmt = connection.createStatement()) {
ResultSet rs = stmt.executeQuery(sql);
assertTrue(rs.next());
assertEquals((long) testData.organization1Id, rs.getLong(Constants.I_ORGANIZATION_PARTS));
assertEquals((long) testData.organization4Id, rs.getLong(Constants.I_ORGANIZATION_PART_OF));
assertTrue(rs.next());
assertEquals((long) testData.organization1Id, rs.getLong(Constants.I_ORGANIZATION_PARTS));
assertEquals((long) testData.organization5Id, rs.getLong(Constants.I_ORGANIZATION_PART_OF));
assertTrue(rs.next());
assertEquals((long) testData.organization2Id, rs.getLong(Constants.I_ORGANIZATION_PARTS));
assertEquals((long) testData.organization1Id, rs.getLong(Constants.I_ORGANIZATION_PART_OF));
assertTrue(rs.next());
assertEquals((long) testData.organization4Id, rs.getLong(Constants.I_ORGANIZATION_PARTS));
assertEquals((long) testData.organization2Id, rs.getLong(Constants.I_ORGANIZATION_PART_OF));
rs.close();
}
});
}
}

View File

@ -0,0 +1,52 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.model.IPreferences;
import dst.ass1.jpa.model.IRider;
import dst.ass1.jpa.util.Constants;
import org.junit.Rule;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
/**
* Tests the constraint for IRider bank data.
*/
public class Ass1_1_2_01Test {
@Rule
public ORMService orm = new ORMService();
@Test
public void testRiderAccountNoBankCodeConstraint() {
IRider r1 = orm.getModelFactory().createRider();
IRider r2 = orm.getModelFactory().createRider();
IPreferences p1 = orm.getModelFactory().createPreferences();
IPreferences p2 = orm.getModelFactory().createPreferences();
orm.em().persist(p1);
orm.em().persist(p2);
r1.setEmail("p1@example.com");
r2.setEmail("p2@example.com");
r1.setPreferences(p1);
r2.setPreferences(p2);
r1.setTel("tel1");
r2.setTel("tel2");
new UniqueConstraintTester<>(r1, r2, e -> {
e.setAccountNo("uniqueVal1");
e.setBankCode("uniqueVal2");
}).run(orm.getEntityManager());
}
@Test
public void testRiderAccountNoBankCodeConstraintJdbc() {
assertTrue(orm.getDatabaseGateway().isIndex(Constants.T_RIDER, Constants.M_RIDER_ACCOUNT, false));
assertTrue(orm.getDatabaseGateway().isIndex(Constants.T_RIDER, Constants.M_RIDER_BANK_CODE, false));
assertTrue(orm.getDatabaseGateway().isComposedIndex(Constants.T_RIDER, Constants.M_RIDER_ACCOUNT, Constants.M_RIDER_BANK_CODE));
assertTrue(orm.getDatabaseGateway().isNullable(Constants.T_RIDER, Constants.M_RIDER_ACCOUNT));
assertTrue(orm.getDatabaseGateway().isNullable(Constants.T_RIDER, Constants.M_RIDER_BANK_CODE));
}
}

View File

@ -0,0 +1,62 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.model.IPreferences;
import dst.ass1.jpa.model.IRider;
import dst.ass1.jpa.util.Constants;
import org.hibernate.PropertyValueException;
import org.junit.Rule;
import org.junit.Test;
import javax.persistence.PersistenceException;
import java.sql.SQLException;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
/**
* Tests the constraint for IRider email.
*/
public class Ass1_1_2_02Test {
@Rule
public ORMService orm = new ORMService();
@Test
public void testUniqueConstraint() {
new UniqueConstraintTester<>(() -> {
IRider rider = orm.getModelFactory().createRider();
rider.setTel("tel");
IPreferences preferences = orm.getModelFactory().createPreferences();
orm.getEntityManager().persist(preferences);
rider.setPreferences(preferences);
return rider;
}, e -> e.setEmail("unique@example.com"))
.run(orm.getEntityManager());
}
@Test
public void testNotNullConstraint() {
IRider e1 = orm.getModelFactory().createRider();
e1.setEmail(null);
e1.setTel("tel");
IPreferences preferences = orm.getModelFactory().createPreferences();
e1.setPreferences(preferences);
var e = assertThrows(PersistenceException.class, () -> {
orm.em().getTransaction().begin();
orm.em().persist(preferences);
orm.em().persist(e1);
orm.em().flush();
});
assertThat(e.getMessage(), containsString("not-null property"));
assertThat(e.getCause(), is(instanceOf(PropertyValueException.class)));
}
@Test
public void testRiderEmailNotNullConstraintJdbc() throws SQLException {
assertFalse(orm.getDatabaseGateway().isNullable(Constants.T_RIDER, Constants.M_RIDER_EMAIL));
}
}

View File

@ -0,0 +1,52 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.dao.IRiderDAO;
import dst.ass1.jpa.model.IRider;
import dst.ass1.jpa.util.Constants;
import org.junit.Before;
import org.junit.Test;
import javax.persistence.Query;
import static org.junit.Assert.*;
public class Ass1_2_1aTest extends Ass1_TestBase {
private IRiderDAO dao;
private Class<? extends IRider> entityClass;
@Before
public void setUp() throws Exception {
dao = daoFactory.createRiderDAO();
entityClass = modelFactory.createRider().getClass();
}
@Test
public void namedQuery_withEmailParameter_returnsNonEmptyResultSet() throws Exception {
Query query = em.createNamedQuery(Constants.Q_RIDER_BY_EMAIL);
try {
query.setParameter("email", TestData.RIDER_1_EMAIL);
} catch (IllegalArgumentException e) {
throw new AssertionError("Could not set parameter 'email' in named query " + Constants.Q_RIDER_BY_EMAIL, e);
}
assertEquals("Expected exactly one result", 1, query.getResultList().size());
}
@Test
public void findByEmail_returnsCorrectResult() throws Exception {
Long riderId = testData.rider1Id;
IRider actual = dao.findByEmail(TestData.RIDER_1_EMAIL);
IRider expected = em.find(entityClass, riderId);
assertEquals(riderId, actual.getId());
assertSame(expected, actual); // note that they should actually be the same object due EntityManager caching!
}
@Test
public void findByEmail_withNonExistingEmail_returnsNull() throws Exception {
assertNull(dao.findByEmail("non@existing.com"));
}
}

View File

@ -0,0 +1,62 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.dao.IDriverDAO;
import dst.ass1.jpa.model.IDriver;
import dst.ass1.jpa.util.Constants;
import org.junit.Test;
import javax.persistence.TypedQuery;
import java.util.Collection;
import java.util.List;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
public class Ass1_2_1bTest extends Ass1_TestBase {
@Test
public void namedQuery_returnsCorrectResult() throws Exception {
TypedQuery<IDriver> singleResultQuery = em.createNamedQuery(Constants.Q_ACTIVE_IN_MULITIPLE_ORGANIZATIONS_DRIVERS, IDriver.class);
singleResultQuery.setParameter("organizations", 2L);
List<IDriver> resultList = singleResultQuery.getResultList();
assertThat("Expected a single result", resultList.size(), is(1));
IDriver result = resultList.get(0);
assertThat(result.getName(), is(TestData.DRIVER_1_NAME));
TypedQuery<IDriver> twoResultsQuery = em.createNamedQuery(Constants.Q_ACTIVE_IN_MULITIPLE_ORGANIZATIONS_DRIVERS, IDriver.class);
twoResultsQuery.setParameter("organizations", 1L);
List<IDriver> twoResults = twoResultsQuery.getResultList();
assertThat("Expected two results", twoResults.size(), is(2));
List<String> names = map(twoResults, IDriver::getName);
assertThat(names, hasItems(TestData.DRIVER_1_NAME, TestData.DRIVER_2_NAME));
}
@Test
public void daoFind_returnsCorrectResult() throws Exception {
IDriverDAO dao = daoFactory.createDriverDAO();
Collection<IDriver> resultList;
resultList = dao.findActiveInMultipleOrganizationsDrivers(3L);
assertThat("Expected an empty result for " + 3, resultList.isEmpty(), is(true));
resultList = dao.findActiveInMultipleOrganizationsDrivers(4L);
assertThat("Expected an empty result for " + 4, resultList.isEmpty(), is(true));
resultList = dao.findActiveInMultipleOrganizationsDrivers(2L);
assertThat("Expected a single results for " + 2, resultList.size(), is(1));
IDriver result = resultList.iterator().next();
assertThat(result.getName(), is(TestData.DRIVER_1_NAME));
resultList = dao.findActiveInMultipleOrganizationsDrivers(1L);
assertThat("Expected two results for " + 1, resultList.size(), is(2));
List<String> names = map(resultList, IDriver::getName);
assertThat(names, hasItems(TestData.DRIVER_1_NAME, TestData.DRIVER_2_NAME));
}
}

View File

@ -0,0 +1,96 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.dao.IDriverDAO;
import dst.ass1.jpa.dao.ILocationDAO;
import dst.ass1.jpa.model.*;
import dst.ass1.jpa.util.Constants;
import org.junit.Test;
import javax.persistence.EntityTransaction;
import javax.persistence.TypedQuery;
import java.math.BigDecimal;
import java.util.Date;
import static dst.ass1.jpa.tests.TestData.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class Ass1_2_1cTest extends Ass1_TestBase {
@Test
public void namedQuery_returnsCorrectResult() {
TypedQuery<Double> q = em.createNamedQuery(Constants.Q_SUM_DISTANCE_MOST_RECENT_TRIP, Double.class);
Double result = q.getSingleResult();
assertNotNull(result);
assertEquals(TRIP_2_DISTANCE + TRIP_4_DISTANCE, result, 0.0);
}
@Test
public void namedQuery_withAdditionalAssociation_returnsCorrectResult() throws Exception {
EntityTransaction tx = em.getTransaction();
tx.begin();
ITrip trip = modelFactory.createTrip();
ITripInfo tripInfo = modelFactory.createTripInfo();
IMatch match = modelFactory.createMatch();
IDriverDAO driverDAO = daoFactory.createDriverDAO();
IDriver driver = driverDAO.findById(testData.driver2Id);
IRider rider = daoFactory.createRiderDAO().findById(testData.rider1Id);
ILocationDAO locationDAO = daoFactory.createLocationDAO();
ILocation pickup = locationDAO.findById(testData.location1Id);
ILocation destination = locationDAO.findById(testData.location2Id);
IVehicle vehicle = daoFactory.createVehicleDAO().findById(testData.vehicle1Id);
IMoney fare = modelFactory.createMoney();
fare.setCurrency(CURRENCY_1);
fare.setValue(BigDecimal.TEN);
IMoney total = modelFactory.createMoney();
total.setCurrency(CURRENCY_1);
total.setValue(BigDecimal.TEN);
match.setDate(new Date());
match.setFare(fare);
match.setDriver(driver);
match.setVehicle(vehicle);
match.setTrip(trip);
trip.setCreated(new Date());
trip.setUpdated(new Date());
trip.setState(TripState.COMPLETED);
trip.setPickup(pickup);
trip.setDestination(destination);
trip.setRider(rider);
trip.setMatch(match);
trip.setTripInfo(tripInfo);
double distance = 22.22;
tripInfo.setDistance(distance);
tripInfo.setCompleted(new Date());
tripInfo.setTotal(total);
tripInfo.setDriverRating(3);
tripInfo.setRiderRating(4);
tripInfo.setTrip(trip);
em.persist(trip);
em.persist(match);
em.persist(tripInfo);
em.flush();
tx.commit();
TypedQuery<Double> q = em.createNamedQuery(Constants.Q_SUM_DISTANCE_MOST_RECENT_TRIP, Double.class);
Double resultList = q.getSingleResult();
assertNotNull(resultList);
assertEquals(TRIP_1_DISTANCE + TRIP_5_DISTANCE + distance, resultList, 0.0);
}
@Test
public void daoFind_returnsCorrectResult() {
double result = daoFactory.createRiderDAO().getTotalDistanceOfMostRecentRider();
assertEquals(TRIP_2_DISTANCE + TRIP_4_DISTANCE, result, 0.0);
}
}

View File

@ -0,0 +1,132 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.dao.IDAOFactory;
import dst.ass1.jpa.dao.IDriverDAO;
import dst.ass1.jpa.dao.ILocationDAO;
import dst.ass1.jpa.dao.impl.DAOFactory;
import dst.ass1.jpa.model.*;
import dst.ass1.jpa.util.Constants;
import org.junit.Before;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import static dst.ass1.jpa.tests.TestData.*;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
public class Ass1_2_2Test extends Ass1_TestBase {
private ILocationDAO locationDAO;
@Before
public void setUp() throws Exception {
// makes sure there's no cache from creating entities
EntityManager em = orm.createEntityManager();
IDAOFactory daoFactory = new DAOFactory(em);
locationDAO = daoFactory.createLocationDAO();
}
@Test
public void testReachedLocationsExists() {
em.createNamedQuery(Constants.Q_REACHED_LOCATIONS);
}
@Test
public void testReachedLocationsQuery() {
Collection<Long> ids = locationDAO.findReachedLocationIds();
assertThat(ids.size(), is(5));
assertThat(ids, hasItems(LOCATION_1_ID, LOCATION_2_ID, LOCATION_3_ID, LOCATION_4_ID, LOCATION_5_ID));
}
@Test
public void testReachedLocationsQuery_withAdditionalAssociations() {
EntityTransaction tx = em.getTransaction();
tx.begin();
final Long ADD_REACHED_1 = 12L;
final Long ADD_REACHED_2 = 13L;
ILocation location1 = modelFactory.createLocation();
location1.setLocationId(11L);
location1.setName("location11");
ILocation location2 = modelFactory.createLocation();
location2.setLocationId(ADD_REACHED_1);
location2.setName("location12");
ILocation location3 = modelFactory.createLocation();
location3.setLocationId(ADD_REACHED_2);
location3.setName("location13");
ILocation location4 = modelFactory.createLocation();
location4.setLocationId(14L);
location4.setName("location14");
ITrip trip = modelFactory.createTrip();
ITripInfo tripInfo = modelFactory.createTripInfo();
IMatch match = modelFactory.createMatch();
IDriverDAO driverDAO = daoFactory.createDriverDAO();
IDriver driver = driverDAO.findById(testData.driver2Id);
IRider rider = daoFactory.createRiderDAO().findById(testData.rider1Id);
IVehicle vehicle = daoFactory.createVehicleDAO().findById(testData.vehicle1Id);
IMoney fare = modelFactory.createMoney();
fare.setCurrency(CURRENCY_1);
fare.setValue(BigDecimal.TEN);
IMoney total = modelFactory.createMoney();
total.setCurrency(CURRENCY_1);
total.setValue(BigDecimal.TEN);
match.setDate(new Date());
match.setFare(fare);
match.setDriver(driver);
match.setVehicle(vehicle);
match.setTrip(trip);
trip.setCreated(new Date());
trip.setUpdated(new Date());
trip.setState(TripState.COMPLETED);
trip.setPickup(location1);
trip.setDestination(location2);
trip.setRider(rider);
trip.setMatch(match);
trip.setTripInfo(tripInfo);
List<ILocation> stops = new LinkedList<>();
stops.add(location3);
trip.setStops(stops);
tripInfo.setDistance(22.22);
tripInfo.setCompleted(createDate(2016, 2, 23, 2, 2));
tripInfo.setTotal(total);
tripInfo.setDriverRating(3);
tripInfo.setRiderRating(4);
tripInfo.setTrip(trip);
em.persist(location1);
em.persist(location2);
em.persist(location3);
em.persist(location4);
em.persist(trip);
em.persist(match);
em.persist(tripInfo);
em.flush();
tx.commit();
Collection<Long> ids = locationDAO.findReachedLocationIds();
assertThat(ids, hasItems(LOCATION_1_ID, LOCATION_2_ID, LOCATION_3_ID, LOCATION_4_ID, LOCATION_5_ID, ADD_REACHED_1, ADD_REACHED_2));
}
@Test
public void testReachedLocationsQuery_onEmptyDatabase() {
db.truncateTables();
Collection<Long> ids = locationDAO.findReachedLocationIds();
assertTrue(ids.isEmpty());
}
}

View File

@ -0,0 +1,97 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.dao.IRiderDAO;
import dst.ass1.jpa.model.IMoney;
import dst.ass1.jpa.model.IRider;
import org.junit.Before;
import org.junit.Test;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
import java.util.stream.Collectors;
import static dst.ass1.jpa.tests.TestData.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
public class Ass1_2_3a_01Test extends Ass1_TestBase {
private IRiderDAO riderDAO;
static Map<Long, Map<String, IMoney>> convertMapKeys(Map<IRider, Map<String, IMoney>> result) {
return result.entrySet().stream().collect(Collectors.toMap(
kv -> kv.getKey().getId(),
kv -> kv.getValue()
));
}
@Before
public void setUp() throws Exception {
riderDAO = daoFactory.createRiderDAO();
}
@Test
public void testRecentspending() {
final IMoney spendingCurrency1Rider1 = modelFactory.createMoney();
spendingCurrency1Rider1.setValue(TRIP_INFO_1_MONEY_VALUE);
spendingCurrency1Rider1.setCurrency(CURRENCY_1);
final IMoney spendingCurrency2Rider1 = modelFactory.createMoney();
spendingCurrency2Rider1.setValue(TRIP_INFO_5_MONEY_VALUE);
spendingCurrency2Rider1.setCurrency(CURRENCY_2);
final IMoney spendingCurrency1Rider2 = modelFactory.createMoney();
spendingCurrency1Rider2.setValue(TRIP_INFO_4_MONEY_VALUE);
spendingCurrency1Rider2.setCurrency(CURRENCY_1);
final IMoney spendingCurrency2Rider2 = modelFactory.createMoney();
spendingCurrency2Rider2.setValue(TRIP_INFO_2_MONEY_VALUE);
spendingCurrency2Rider2.setCurrency(CURRENCY_2);
final IMoney spendingCurrency3Rider3 = modelFactory.createMoney();
spendingCurrency3Rider3.setValue(TRIP_INFO_3_MONEY_VALUE);
spendingCurrency3Rider3.setCurrency(CURRENCY_3);
Map<IRider, Map<String, IMoney>> spending = riderDAO.getRecentSpending();
assertThat(spending.size(), is(3));
Map<Long, Map<String, IMoney>> mapped = convertMapKeys(spending);
assertTrue(mapped.containsKey(testData.rider1Id));
assertTrue(mapped.containsKey(testData.rider2Id));
assertTrue(mapped.containsKey(testData.rider3Id));
assertThat(mapped.get(testData.rider1Id).size(), is(2));
assertThat(mapped.get(testData.rider2Id).size(), is(2));
assertThat(mapped.get(testData.rider3Id).size(), is(1));
assertTrue(mapped.get(testData.rider1Id).containsKey(CURRENCY_1));
assertTrue(mapped.get(testData.rider1Id).containsKey(CURRENCY_2));
assertTrue(mapped.get(testData.rider2Id).containsKey(CURRENCY_1));
assertTrue(mapped.get(testData.rider2Id).containsKey(CURRENCY_2));
assertTrue(mapped.get(testData.rider3Id).containsKey(CURRENCY_3));
assertEquals(spendingCurrency1Rider1.getValue(), scaleDown(mapped.get(testData.rider1Id).get(CURRENCY_1)));
assertEquals(spendingCurrency2Rider1.getValue(), scaleDown(mapped.get(testData.rider1Id).get(CURRENCY_2)));
assertEquals(spendingCurrency1Rider2.getValue(), scaleDown(mapped.get(testData.rider2Id).get(CURRENCY_1)));
assertEquals(spendingCurrency2Rider2.getValue(), scaleDown(mapped.get(testData.rider2Id).get(CURRENCY_2)));
assertEquals(spendingCurrency3Rider3.getValue(), scaleDown(mapped.get(testData.rider3Id).get(CURRENCY_3)));
}
@Test
public void testRecentSpending_onEmptyDatabase() {
db.truncateTables();
Map<IRider, Map<String, IMoney>> recentSpending = riderDAO.getRecentSpending();
assertTrue(recentSpending.isEmpty());
}
private BigDecimal scaleDown(IMoney money) {
return money.getValue().setScale(0, RoundingMode.DOWN);
}
}

View File

@ -0,0 +1,122 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.dao.IRiderDAO;
import dst.ass1.jpa.dao.ITripDAO;
import dst.ass1.jpa.model.*;
import org.junit.Before;
import org.junit.Test;
import javax.persistence.EntityTransaction;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Map;
import java.util.stream.Collectors;
import static dst.ass1.jpa.tests.TestData.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
public class Ass1_2_3a_02Test extends Ass1_TestBase {
private static final BigDecimal TRIP_INFO_9_VALUE = new BigDecimal(55.0);
private ITripDAO tripDAO;
private IRiderDAO riderDAO;
static Map<Long, Map<String, IMoney>> convertMapKeys(Map<IRider, Map<String, IMoney>> result) {
return result.entrySet().stream().collect(Collectors.toMap(
kv -> kv.getKey().getId(),
kv -> kv.getValue()
));
}
@Before
public void setUpDatabase() throws Exception {
tripDAO = daoFactory.createTripDAO();
riderDAO = daoFactory.createRiderDAO();
IMoney total = modelFactory.createMoney();
total.setValue(TRIP_INFO_9_VALUE);
total.setCurrency(CURRENCY_2);
EntityTransaction tx = em.getTransaction();
tx.begin();
ITrip trip = tripDAO.findById(testData.trip9Id);
trip.setState(TripState.COMPLETED);
ITripInfo tripInfo = modelFactory.createTripInfo();
tripInfo.setTrip(trip);
tripInfo.setRiderRating(3);
tripInfo.setDriverRating(3);
tripInfo.setTotal(total);
tripInfo.setCompleted(new Date());
tripInfo.setDistance(2.2);
trip.setTripInfo(tripInfo);
em.persist(tripInfo);
em.flush();
tx.commit();
}
@Test
public void testRecentspending() {
final IMoney spendingCurrency1Rider1 = modelFactory.createMoney();
spendingCurrency1Rider1.setValue(TRIP_INFO_1_MONEY_VALUE);
spendingCurrency1Rider1.setCurrency(CURRENCY_1);
final IMoney spendingCurrency2Rider1 = modelFactory.createMoney();
spendingCurrency2Rider1.setValue(TRIP_INFO_5_MONEY_VALUE.add(TRIP_INFO_9_VALUE));
spendingCurrency2Rider1.setCurrency(CURRENCY_2);
final IMoney spendingCurrency1Rider2 = modelFactory.createMoney();
spendingCurrency1Rider2.setValue(TRIP_INFO_4_MONEY_VALUE);
spendingCurrency1Rider2.setCurrency(CURRENCY_1);
final IMoney spendingCurrency2Rider2 = modelFactory.createMoney();
spendingCurrency2Rider2.setValue(TRIP_INFO_2_MONEY_VALUE);
spendingCurrency2Rider2.setCurrency(CURRENCY_2);
final IMoney spendingCurrency3Rider3 = modelFactory.createMoney();
spendingCurrency3Rider3.setValue(TRIP_INFO_3_MONEY_VALUE);
spendingCurrency3Rider3.setCurrency(CURRENCY_3);
Map<IRider, Map<String, IMoney>> spending = riderDAO.getRecentSpending();
assertThat(spending.size(), is(3));
Map<Long, Map<String, IMoney>> mapped = convertMapKeys(spending);
assertTrue(mapped.containsKey(testData.rider1Id));
assertTrue(mapped.containsKey(testData.rider2Id));
assertTrue(mapped.containsKey(testData.rider3Id));
assertThat(mapped.get(testData.rider1Id).size(), is(2));
assertThat(mapped.get(testData.rider2Id).size(), is(2));
assertThat(mapped.get(testData.rider3Id).size(), is(1));
assertTrue(mapped.get(testData.rider1Id).containsKey(CURRENCY_1));
assertTrue(mapped.get(testData.rider1Id).containsKey(CURRENCY_2));
assertTrue(mapped.get(testData.rider2Id).containsKey(CURRENCY_2));
assertTrue(mapped.get(testData.rider2Id).containsKey(CURRENCY_2));
assertTrue(mapped.get(testData.rider3Id).containsKey(CURRENCY_3));
assertEquals(spendingCurrency1Rider1.getValue(), scaleDown(mapped.get(testData.rider1Id).get(CURRENCY_1)));
assertEquals(spendingCurrency2Rider1.getValue(), scaleDown(mapped.get(testData.rider1Id).get(CURRENCY_2)));
assertEquals(spendingCurrency1Rider2.getValue(), scaleDown(mapped.get(testData.rider2Id).get(CURRENCY_1)));
assertEquals(spendingCurrency2Rider2.getValue(), scaleDown(mapped.get(testData.rider2Id).get(CURRENCY_2)));
assertEquals(spendingCurrency3Rider3.getValue(), scaleDown(mapped.get(testData.rider3Id).get(CURRENCY_3)));
}
@Test
public void testRecentSpending_onEmptyDatabase() {
db.truncateTables();
Map<IRider, Map<String, IMoney>> recentSpending = riderDAO.getRecentSpending();
assertTrue(recentSpending.isEmpty());
}
private BigDecimal scaleDown(IMoney money) {
return money.getValue().setScale(0, RoundingMode.DOWN);
}
}

View File

@ -0,0 +1,86 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.dao.ITripDAO;
import dst.ass1.jpa.model.ITrip;
import org.junit.Before;
import org.junit.Test;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.core.IsCollectionContaining.hasItems;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
public class Ass1_2_3b_01Test extends Ass1_TestBase {
private ITripDAO dao;
@Before
public void setUp() throws Exception {
dao = daoFactory.createTripDAO();
}
@Test
public void testFindCanceledTripsBetweenStartAndFinish() {
Collection<ITrip> trips = dao.findCancelledTrips(null, null);
Collection<Long> ids = map(trips, ITrip::getId);
assertThat(ids.size(), is(7));
assertThat(ids, hasItems(testData.trip8Id, testData.trip11Id, testData.trip12Id, testData.trip13Id, testData.trip14Id, testData.trip15Id, testData.trip16Id));
}
@Test
public void testFindCanceledTripsCreatedBetweenStartAndFinish2() {
Date start = createDate(2019, 1, 1, 1, 1);
Collection<ITrip> trips = dao.findCancelledTrips(start, null);
Collection<Long> ids = map(trips, ITrip::getId);
assertThat(ids.size(), is(4));
assertThat(ids, hasItems(testData.trip8Id, testData.trip13Id, testData.trip14Id, testData.trip15Id));
}
@Test
public void testFindCanceledTripsForStatusCreatedBetweenStartAndFinish3() {
Date start = dao.findById(testData.trip15Id).getCreated();
Collection<ITrip> trips = dao.findCancelledTrips(start, null);
Collection<Long> ids = map(trips, ITrip::getId);
assertThat(ids.size(), is(1));
assertThat(ids, hasItems(testData.trip8Id));
}
@Test
public void testFindCanceledTripsForStatusCreatedBetweenStartAndFinish4() {
Date end = dao.findById(testData.trip11Id).getCreated();
Collection<ITrip> trips = dao.findCancelledTrips(null, end);
assertThat(trips.size(), is(1));
assertThat(map(trips, ITrip::getId), hasItems(testData.trip12Id));
}
@Test
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish5() {
Date start = dao.findById(testData.trip12Id).getCreated();
Date end = dao.findById(testData.trip15Id).getCreated();
Collection<ITrip> trips = dao.findCancelledTrips(start, end);
assertThat(trips.size(), is(4));
assertThat(map(trips, ITrip::getId), hasItems(testData.trip11Id, testData.trip13Id, testData.trip14Id, testData.trip16Id));
}
@Test
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish6() {
Date start = dao.findById(testData.trip8Id).getCreated();
Collection<ITrip> cancelledTrips = dao.findCancelledTrips(start, null);
assertTrue(cancelledTrips.isEmpty());
}
private Date createDate(int year, int month, int day, int hours, int minutes) {
return new GregorianCalendar(year, month, day, hours, minutes).getTime();
}
}

View File

@ -0,0 +1,77 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.dao.ITripDAO;
import dst.ass1.jpa.model.ITrip;
import dst.ass1.jpa.model.TripState;
import org.junit.Before;
import org.junit.Test;
import javax.persistence.EntityTransaction;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.core.IsCollectionContaining.hasItems;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
public class Ass1_2_3b_02Test extends Ass1_TestBase {
private ITripDAO dao;
@Before
public void setUp() throws Exception {
dao = daoFactory.createTripDAO();
EntityTransaction tx = em.getTransaction();
tx.begin();
ITrip trip = dao.findById(testData.trip6Id);
trip.setState(TripState.CANCELLED);
em.persist(trip);
em.flush();
tx.commit();
}
@Test
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish() {
Collection<ITrip> trips = dao.findCancelledTrips(null, null);
Collection<Long> ids = map(trips, ITrip::getId);
assertThat(ids.size(), is(8));
assertThat(ids, hasItems(testData.trip6Id, testData.trip8Id, testData.trip11Id, testData.trip12Id, testData.trip13Id, testData.trip14Id, testData.trip15Id, testData.trip16Id));
}
@Test
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish2() {
Date start = createDate(2019, 1, 1, 1, 1);
Collection<ITrip> trips = dao.findCancelledTrips(start, null);
Collection<Long> ids = map(trips, ITrip::getId);
assertThat(ids.size(), is(5));
assertThat(ids, hasItems(testData.trip6Id, testData.trip8Id, testData.trip13Id, testData.trip14Id, testData.trip15Id));
}
@Test
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish3() {
Date start = dao.findById(testData.trip12Id).getCreated();
Date end = dao.findById(testData.trip15Id).getCreated();
Collection<ITrip> trips = dao.findCancelledTrips(start, end);
assertThat(trips.size(), is(5));
assertThat(map(trips, ITrip::getId), hasItems(testData.trip6Id, testData.trip11Id, testData.trip13Id, testData.trip14Id, testData.trip16Id));
}
@Test
public void testFindCanceledEventsForStatusCreatedBetweenStartAndFinish4() {
Date start = dao.findById(testData.trip8Id).getCreated();
Collection<ITrip> cancelledTrips = dao.findCancelledTrips(start, null);
assertTrue(cancelledTrips.isEmpty());
}
private Date createDate(int year, int month, int day, int hours, int minutes) {
return new GregorianCalendar(year, month, day, hours, minutes).getTime();
}
}

View File

@ -0,0 +1,109 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.model.ILocation;
import dst.ass1.jpa.model.ITrip;
import dst.ass1.jpa.model.TripState;
import org.junit.Rule;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import java.util.Date;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertNotNull;
import static org.hamcrest.MatcherAssert.assertThat;
public class Ass1_3_1Test {
@Rule
public ORMService orm = new ORMService();
@Test
public void entityListener_prePersistSetsPropertiesCorrectly() throws InterruptedException {
Date then = new Date();
Thread.sleep(50);
EntityManager em = orm.getEntityManager();
ILocation pickup = orm.getModelFactory().createLocation();
pickup.setName("name1");
pickup.setLocationId(1L);
ILocation destination = orm.getModelFactory().createLocation();
destination.setName("name2");
destination.setLocationId(2L);
ITrip trip = orm.getModelFactory().createTrip();
trip.setState(TripState.CREATED);
trip.setPickup(pickup);
trip.setDestination(destination);
EntityTransaction tx;
// persist
tx = em.getTransaction();
tx.begin();
em.persist(pickup);
em.persist(destination);
em.persist(trip);
em.flush();
tx.commit();
assertNotNull(trip.getCreated());
assertNotNull(trip.getUpdated());
assertThat(trip.getCreated(), greaterThan(then));
assertThat(trip.getUpdated(), greaterThan(then));
}
@Test
public void entityListener_preUpdateSetsPropertiesCorrectly() throws InterruptedException {
EntityManager em = orm.getEntityManager();
ILocation pickup = orm.getModelFactory().createLocation();
pickup.setName("name1");
pickup.setLocationId(1L);
ILocation destination = orm.getModelFactory().createLocation();
destination.setName("name2");
destination.setLocationId(2L);
ITrip trip = orm.getModelFactory().createTrip();
trip.setCreated(new Date());
trip.setUpdated(new Date());
trip.setState(TripState.CREATED);
trip.setPickup(pickup);
trip.setDestination(destination);
EntityTransaction tx;
// persist
tx = em.getTransaction();
tx.begin();
em.persist(pickup);
em.persist(destination);
em.persist(trip);
em.flush();
tx.commit();
Date then = new Date();
Thread.sleep(2000);
// update
tx = em.getTransaction();
tx.begin();
trip.setState(TripState.QUEUED);
em.persist(trip);
em.flush();
tx.commit();
assertNotNull(trip.getUpdated());
assertThat(trip.getUpdated(), greaterThan(then));
}
}

View File

@ -0,0 +1,69 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.dao.IDAOFactory;
import dst.ass1.jpa.listener.DefaultListener;
import dst.ass1.jpa.model.IModelFactory;
import dst.ass1.jpa.model.IVehicle;
import org.junit.Rule;
import org.junit.Test;
import javax.persistence.EntityManager;
import java.util.List;
import static org.junit.Assert.*;
public class Ass1_3_2Test {
@Rule
public ORMService orm = new ORMService();
@Test
public void testDefaultListener() {
DefaultListener.clear();
IDAOFactory daoFactory = orm.getDaoFactory();
IModelFactory modelFactory = orm.getModelFactory();
EntityManager em = orm.getEntityManager();
em.getTransaction().begin();
// do some inserts
IVehicle vehicle = modelFactory.createVehicle();
vehicle.setLicense(TestData.VEHICLE_1_LICENSE);
vehicle.setType(TestData.TYPE_1);
vehicle.setColor(TestData.COLOR_1);
em.persist(vehicle);
em.flush();
em.remove(vehicle);
em.flush();
vehicle = modelFactory.createVehicle();
vehicle.setLicense(TestData.VEHICLE_2_LICENSE);
vehicle.setType(TestData.TYPE_2);
vehicle.setColor(TestData.COLOR_2);
em.persist(vehicle);
assertEquals(1, DefaultListener.getRemoveOperations());
assertTrue(DefaultListener.getPersistOperations() > 0);
assertEquals((double) DefaultListener.getOverallTimeToPersist() / DefaultListener.getPersistOperations(), DefaultListener.getAverageTimeToPersist(), 0.6);
List<IVehicle> vehicles = daoFactory.createVehicleDAO().findAll();
assertNotNull(vehicles);
assertFalse(vehicles.isEmpty());
int loadOperations = DefaultListener.getLoadOperations();
em.refresh(vehicles.get(0));
assertEquals(loadOperations + 1, DefaultListener.getLoadOperations());
vehicles = daoFactory.createVehicleDAO().findAll();
assertNotNull(vehicles);
assertFalse(vehicles.isEmpty());
vehicles.get(0).setLicense("updated");
em.persist(vehicles.get(0));
em.flush();
assertEquals(1, DefaultListener.getUpdateOperations());
}
}

View File

@ -0,0 +1,38 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.interceptor.SQLInterceptor;
import dst.ass1.jpa.util.Constants;
import org.junit.Test;
import javax.persistence.Query;
import static org.junit.Assert.assertEquals;
public class Ass1_3_3Test extends Ass1_TestBase {
@Test
public void sqlInterceptor_countsSelectsCorrectly() {
em.getTransaction().begin();
SQLInterceptor.resetCounter();
assertEquals(0, SQLInterceptor.getSelectCount());
Query c = em.createQuery("select v from " + Constants.T_VEHICLE + " v");
c.getResultList();
assertEquals(0, SQLInterceptor.getSelectCount());
c = em.createQuery("select distinct l from " + Constants.T_LOCATION + " l");
c.getResultList();
assertEquals(1, SQLInterceptor.getSelectCount());
c = em.createQuery("select t from " + Constants.T_TRIP + " t");
c.getResultList();
assertEquals(2, SQLInterceptor.getSelectCount());
c = em.createQuery("select distinct t from " + Constants.T_TRIP + " t");
c.getResultList();
assertEquals(3, SQLInterceptor.getSelectCount());
}
}

View File

@ -0,0 +1,12 @@
package dst.ass1.jpa.tests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses( {
Ass1_1_1_00Test.class, Ass1_1_1_01Test.class, Ass1_1_1_02Test.class, Ass1_1_1_03Test.class, Ass1_1_1_04Test.class, Ass1_1_1_05Test.class, Ass1_1_1_06Test.class, Ass1_1_1_07Test.class, Ass1_1_1_08Test.class, Ass1_1_1_09Test.class, Ass1_1_1_10Test.class, Ass1_1_2_01Test.class, Ass1_1_2_02Test.class, Ass1_2_1aTest.class, Ass1_2_1bTest.class, Ass1_2_1cTest.class, Ass1_2_2Test.class, Ass1_2_3a_01Test.class, Ass1_2_3a_02Test.class, Ass1_2_3b_01Test.class, Ass1_2_3b_02Test.class, Ass1_3_1Test.class, Ass1_3_2Test.class, Ass1_3_3Test.class
})
public class Ass1_Suite {
}

View File

@ -0,0 +1,45 @@
package dst.ass1.jpa.tests;
import dst.ass1.jpa.DatabaseGateway;
import dst.ass1.jpa.ORMService;
import dst.ass1.jpa.dao.IDAOFactory;
import dst.ass1.jpa.model.IModelFactory;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.ErrorCollector;
import javax.persistence.EntityManager;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Ass1_TestBase {
protected final TestData testData = new TestData();
@Rule
public ORMService orm = new ORMService(testData);
@Rule
public ErrorCollector err = new ErrorCollector();
// commonly used classes unwrapped from ORMService
protected EntityManager em;
protected IModelFactory modelFactory;
protected IDAOFactory daoFactory;
protected DatabaseGateway db;
public static <T, R> List<R> map(Collection<T> collection, Function<T, R> fn) {
return collection.stream().map(fn).collect(Collectors.toList());
}
@Before
public void setUpBase() throws Exception {
em = orm.getEntityManager();
modelFactory = orm.getModelFactory();
daoFactory = orm.getDaoFactory();
db = orm.getDatabaseGateway();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
package dst.ass1.jpa.tests;
import org.hibernate.exception.ConstraintViolationException;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceException;
import java.util.function.Consumer;
import java.util.function.Supplier;
import static org.junit.Assert.fail;
/**
* Tests a unique constraint by creating two instances of an entity, calling the same value setter on each entity,
* and finally trying to persist them.
*
* @param <E> the entity type
*/
public class UniqueConstraintTester<E> {
private Consumer<E> valueSetter;
private E e1;
private E e2;
public UniqueConstraintTester(E e1, E e2, Consumer<E> valueSetter) {
this.e1 = e1;
this.e2 = e2;
this.valueSetter = valueSetter;
}
public UniqueConstraintTester(Supplier<E> entityFactory, Consumer<E> valueSetter) {
this(entityFactory.get(), entityFactory.get(), valueSetter);
}
public void run(EntityManager em) {
EntityTransaction tx = em.getTransaction();
if (!tx.isActive()) {
tx.begin();
}
valueSetter.accept(e1);
em.persist(e1);
em.flush();
try {
valueSetter.accept(e2);
em.persist(e2);
em.flush();
fail("Missing unique constraint in " + e2.getClass());
} catch (PersistenceException e) {
Throwable cause = e.getCause();
if (!(cause instanceof ConstraintViolationException)) {
fail("Missing unique constraint in " + e2.getClass());
}
}
}
}

View File

@ -0,0 +1,16 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - %highlight(%5p) [%12.12thread] %cyan(%-40.40logger{39}): %m%n</pattern>
</encoder>
</appender>
<logger name="org.hibernate" level="WARN"/>
<root level="${log.level:-INFO}">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

27
ass1-kv/pom.xml Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>at.ac.tuwien.infosys.dst</groupId>
<artifactId>dst</artifactId>
<version>2021.1</version>
<relativePath>..</relativePath>
</parent>
<artifactId>ass1-kv</artifactId>
<packaging>jar</packaging>
<name>DST :: Assignment 1 :: Key-Value Store</name>
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,69 @@
package dst.ass1.kv;
public interface ISessionManager {
/**
* Creates a new session id and stores the userId and session timeout under the given id in the session store.
*
* @param userId the user to create the session for
* @param timeToLive the session timeout after which the session expires in seconds
* @return the session id.
* @throws SessionCreationFailedException if the session couldn't be created, e.g., due to a failed transaction
*/
String createSession(Long userId, int timeToLive) throws SessionCreationFailedException;
/**
* Sets a key--value pair in the given session.
*
* @param sessionId the session to store the variable in
* @param key the name of the variable
* @param value the value
* @throws SessionNotFoundException if the session wasn't found
*/
void setSessionVariable(String sessionId, String key, String value) throws SessionNotFoundException;
/**
* Returns the value of the given session variable.
*
* @param sessionId the session id
* @param key the name of the variable
* @return the variable value, or null if it doesn't exist
* @throws SessionNotFoundException if the given session id has expired or doesn't exist
*/
String getSessionVariable(String sessionId, String key) throws SessionNotFoundException;
/**
* Returns the user to whom the given session belongs.
*
* @param sessionId the session id
* @return the user id
* @throws SessionNotFoundException if the given session id has expired or doesn't exist
*/
Long getUserId(String sessionId) throws SessionNotFoundException;
/**
* Returns the current time-to-live for the given session.
*
* @param sessionId the session id
* @return the session ttl in seconds
* @throws SessionNotFoundException if the given session id has expired or doesn't exist
*/
int getTimeToLive(String sessionId) throws SessionNotFoundException;
/**
* Checks whether the given user has an open session, if so, the session id is returned (and the timeout
* parameter ignored), otherwise a new session is created with the given timeout and the newly generated id is
* returned.
*
* @param userId the user to require the session for
* @param timeToLive the session timeout after which the session expires in seconds
* @return the session id.
* @throws SessionCreationFailedException if the session couldn't be created, e.g., due to a failed transaction
*/
String requireSession(Long userId, int timeToLive) throws SessionCreationFailedException;
/**
* Closes whatever underlying connection is required to maintain the session manager.
*/
void close();
}

View File

@ -0,0 +1,13 @@
package dst.ass1.kv;
import java.util.Properties;
public interface ISessionManagerFactory {
/**
* Creates an implementation of an {@link ISessionManager}.
*
* @param properties the properties to use for instantiation
* @return a session manager object
*/
ISessionManager createSessionManager(Properties properties);
}

View File

@ -0,0 +1,25 @@
package dst.ass1.kv;
/**
* Exception indicating that a request to create a new session could not be fulfilled.
*/
public class SessionCreationFailedException extends Exception {
private static final long serialVersionUID = 1L;
public SessionCreationFailedException() {
}
public SessionCreationFailedException(String message) {
super(message);
}
public SessionCreationFailedException(String message, Throwable cause) {
super(message, cause);
}
public SessionCreationFailedException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,24 @@
package dst.ass1.kv;
/**
* Exception to indicate that <i>this is not the session you are looking for</i>.
*/
public class SessionNotFoundException extends Exception {
private static final long serialVersionUID = 1L;
public SessionNotFoundException() {
}
public SessionNotFoundException(String message) {
super(message);
}
public SessionNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public SessionNotFoundException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,17 @@
package dst.ass1.kv.impl;
import dst.ass1.kv.ISessionManager;
import dst.ass1.kv.ISessionManagerFactory;
import java.util.Properties;
public class SessionManagerFactory implements ISessionManagerFactory {
@Override
public ISessionManager createSessionManager(Properties properties) {
// TODO
// read "redis.host" and "redis.port" from the properties
return null;
}
}

View File

@ -0,0 +1,60 @@
package dst.ass1.kv;
import org.junit.rules.ExternalResource;
import redis.clients.jedis.Jedis;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* Drops the entire key space of a redis instance before and after a test run.
*/
public class RedisCleaner extends ExternalResource {
private Properties properties;
private Jedis jedis;
@Override
protected void before() throws IOException {
properties = loadProperties();
String host = properties.getProperty("redis.host");
int port = Integer.parseInt(properties.getProperty("redis.port"));
jedis = new Jedis(host, port);
// completely clear the redis instance before each test
jedis.flushAll();
}
@Override
protected void after() {
// completely clear the redis instance after each test
try {
jedis.flushAll();
} finally {
// close the connection pool
jedis.close();
}
}
/**
* @return loaded redis properties
*/
public Properties getProperties() {
return properties;
}
public Jedis getJedis() {
return jedis;
}
private Properties loadProperties() throws IOException {
Properties properties = new Properties();
try (InputStream in = getClass().getClassLoader().getResourceAsStream("redis.properties")) {
properties.load(in);
}
return properties;
}
}

View File

@ -0,0 +1,102 @@
package dst.ass1.kv.tests;
import dst.ass1.kv.ISessionManager;
import dst.ass1.kv.ISessionManagerFactory;
import dst.ass1.kv.RedisCleaner;
import dst.ass1.kv.SessionNotFoundException;
import dst.ass1.kv.impl.SessionManagerFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
public class Ass1_5_1Test {
@Rule
public RedisCleaner redisRule = new RedisCleaner();
private ISessionManager sessionManager;
@Before
public void setUp() {
ISessionManagerFactory sessionManagerFactory = new SessionManagerFactory();
sessionManager = sessionManagerFactory.createSessionManager(redisRule.getProperties());
}
@After
public void tearDown() {
sessionManager.close();
}
@Test
public void createSession_createsSessionId() throws Exception {
String sessionId = sessionManager.createSession(1337L, 15000);
assertNotNull(sessionId);
}
@Test
public void getAndSetSessionVariable_behavesCorrectly() throws Exception {
String sessionId = sessionManager.createSession(1337L, 15000);
sessionManager.setSessionVariable(sessionId, "f00", "bar");
assertEquals("bar", sessionManager.getSessionVariable(sessionId, "f00"));
}
@Test(expected = SessionNotFoundException.class)
public void setSessionVariable_forNonExistingSession_throwsSessionNotFoundException() throws Exception {
sessionManager.setSessionVariable("nonExistingSessionId", "f00", "bar");
}
@Test(expected = SessionNotFoundException.class)
public void getSessionVariable_forNonExistingSession_throwsSessionNotFoundException() throws Exception {
sessionManager.getSessionVariable("nonExistingSessionId", "f00");
}
@Test
public void getSessionVariable_onNonExistingVariable_returnsNull() throws Exception {
String sessionId = sessionManager.createSession(1337L, 15000);
String value = sessionManager.getSessionVariable(sessionId, "f00");
assertNull(value);
}
@Test
public void getUserId_returnsCorrectUserID() throws Exception {
Long userId = 1337L;
String sessionId = sessionManager.createSession(userId, 15000);
assertEquals(userId, sessionManager.getUserId(sessionId));
}
@Test(expected = SessionNotFoundException.class)
public void getUserId_forNonExistingSession_throwsException() throws Exception {
sessionManager.getUserId("nonExistingSessionId");
}
@Test
public void getTimeToLive_returnsCorrectValue() throws Exception {
String sessionId = sessionManager.createSession(1337L, 60);
int ttl = sessionManager.getTimeToLive(sessionId);
assertThat(ttl, allOf(greaterThan(57), lessThan(61)));
}
@Test
public void getTimeToLive_afterExpiry_throwsSessionNotFoundException() throws Exception {
String sessionId = sessionManager.createSession(1337L, 2);
int ttl = sessionManager.getTimeToLive(sessionId);
assertThat(ttl, greaterThan(0));
Thread.sleep(3000);
assertThrows(SessionNotFoundException.class, () -> {
sessionManager.getTimeToLive(sessionId);
});
}
@Test(expected = SessionNotFoundException.class)
public void getTimeToLive_forNonExistingSession_throwsSessionNotFoundException() throws Exception {
sessionManager.getTimeToLive("nonExistingSessionId");
}
}

View File

@ -0,0 +1,50 @@
package dst.ass1.kv.tests;
import dst.ass1.kv.ISessionManager;
import dst.ass1.kv.ISessionManagerFactory;
import dst.ass1.kv.RedisCleaner;
import dst.ass1.kv.impl.SessionManagerFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class Ass1_5_2Test {
@Rule
public RedisCleaner redisRule = new RedisCleaner();
private ISessionManager sessionManager;
@Before
public void setUp() {
ISessionManagerFactory sessionManagerFactory = new SessionManagerFactory();
sessionManager = sessionManagerFactory.createSessionManager(redisRule.getProperties());
}
@After
public void tearDown() {
sessionManager.close();
}
@Test
public void testRequireSessionForExistingSession_existingIdReturned() throws Exception {
String newId = sessionManager.createSession(1337L, 30000);
assertNotNull(newId);
String requiredId = sessionManager.requireSession(1337L, 15000);
assertEquals(newId, requiredId);
}
@Test
public void testRequireSessionForNonExistingSession_newSessionCreated() throws Exception {
String sessionId = sessionManager.requireSession(1337L, 15000);
assertEquals(Long.valueOf(1337L), sessionManager.getUserId(sessionId));
}
}

View File

@ -0,0 +1,13 @@
package dst.ass1.kv.tests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses( {
Ass1_5_1Test.class,
Ass1_5_2Test.class
})
public class Ass1_5_Suite {
}

View File

@ -0,0 +1,14 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - %highlight(%5p) [%12.12thread] %cyan(%-40.40logger{39}): %m%n</pattern>
</encoder>
</appender>
<root level="${log.level:-INFO}">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

Some files were not shown because too many files have changed in this diff Show More