#75 Added transaction logic
This commit is contained in:
@@ -9,13 +9,17 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.sqlite.SQLiteDataSource;
|
import org.sqlite.SQLiteDataSource;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.client.DataSourceFactory;
|
import de.rwu.easydrop.api.client.DataSourceFactory;
|
||||||
|
import de.rwu.easydrop.api.dto.OfferDTO;
|
||||||
import de.rwu.easydrop.data.connector.OfferPersistenceInterface;
|
import de.rwu.easydrop.data.connector.OfferPersistenceInterface;
|
||||||
import de.rwu.easydrop.data.connector.ProductPersistenceInterface;
|
import de.rwu.easydrop.data.connector.ProductPersistenceInterface;
|
||||||
import de.rwu.easydrop.data.connector.SQLiteConnector;
|
import de.rwu.easydrop.data.connector.SQLiteConnector;
|
||||||
|
import de.rwu.easydrop.data.connector.TransactionPersistenceInterface;
|
||||||
import de.rwu.easydrop.model.Offer;
|
import de.rwu.easydrop.model.Offer;
|
||||||
import de.rwu.easydrop.model.ProductCatalogue;
|
import de.rwu.easydrop.model.ProductCatalogue;
|
||||||
|
import de.rwu.easydrop.service.mapping.OfferMapper;
|
||||||
import de.rwu.easydrop.service.processing.OfferIdentifier;
|
import de.rwu.easydrop.service.processing.OfferIdentifier;
|
||||||
import de.rwu.easydrop.service.processing.OfferProvisioner;
|
import de.rwu.easydrop.service.processing.OfferProvisioner;
|
||||||
|
import de.rwu.easydrop.service.processing.TransactionHandler;
|
||||||
import de.rwu.easydrop.service.retriever.CatalogueRetriever;
|
import de.rwu.easydrop.service.retriever.CatalogueRetriever;
|
||||||
import de.rwu.easydrop.service.retriever.ProductRetriever;
|
import de.rwu.easydrop.service.retriever.ProductRetriever;
|
||||||
import de.rwu.easydrop.service.writer.CatalogueWriter;
|
import de.rwu.easydrop.service.writer.CatalogueWriter;
|
||||||
@@ -57,6 +61,7 @@ public final class Core {
|
|||||||
ProductRetriever retriever = new ProductRetriever(dataSourceFactory, pdb);
|
ProductRetriever retriever = new ProductRetriever(dataSourceFactory, pdb);
|
||||||
CatalogueRetriever catRetriever = new CatalogueRetriever(pConfig, retriever);
|
CatalogueRetriever catRetriever = new CatalogueRetriever(pConfig, retriever);
|
||||||
CatalogueWriter catWriter = new CatalogueWriter(pdb);
|
CatalogueWriter catWriter = new CatalogueWriter(pdb);
|
||||||
|
TransactionPersistenceInterface tpi = new SQLiteConnector(new SQLiteDataSource());
|
||||||
|
|
||||||
LOGGER.info("Loading catalogues");
|
LOGGER.info("Loading catalogues");
|
||||||
catRetriever.loadCatalogues();
|
catRetriever.loadCatalogues();
|
||||||
@@ -70,8 +75,12 @@ public final class Core {
|
|||||||
provis.runProvisioner(identifiedOffers);
|
provis.runProvisioner(identifiedOffers);
|
||||||
|
|
||||||
LOGGER.info("Creating transactions");
|
LOGGER.info("Creating transactions");
|
||||||
// Transaction logic!
|
TransactionHandler txHandler = new TransactionHandler(tpi);
|
||||||
|
for (OfferDTO o : odb.getOffers()) {
|
||||||
|
txHandler.turnOfferToTransaction(OfferMapper.mapOfferFromDTO(o));
|
||||||
|
}
|
||||||
|
|
||||||
LOGGER.info("Done!");
|
tpi.outputTransactionsToLog();
|
||||||
|
tpi.outputSummaryToLog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
package de.rwu.easydrop.data.connector;
|
package de.rwu.easydrop.data.connector;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.dto.OfferDTO;
|
import de.rwu.easydrop.api.dto.OfferDTO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to offer persistence.
|
||||||
|
*
|
||||||
|
* @since 0.3.0
|
||||||
|
*/
|
||||||
public interface OfferPersistenceInterface {
|
public interface OfferPersistenceInterface {
|
||||||
/**
|
/**
|
||||||
* Writes a ProductDTO to persistence.
|
* Writes a ProductDTO to persistence.
|
||||||
@@ -19,7 +26,21 @@ public interface OfferPersistenceInterface {
|
|||||||
OfferDTO getOfferDTOById(String offerId);
|
OfferDTO getOfferDTOById(String offerId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all data from persistence.
|
* Gets all offerDTOs from persistence.
|
||||||
|
*
|
||||||
|
* @return offerDTOs
|
||||||
*/
|
*/
|
||||||
void clearData();
|
List<OfferDTO> getOffers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all offer data from persistence.
|
||||||
|
*/
|
||||||
|
void clearOfferData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an offer from persistence.
|
||||||
|
*
|
||||||
|
* @param offerId
|
||||||
|
*/
|
||||||
|
void deleteOfferById(String offerId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public interface ProductPersistenceInterface {
|
|||||||
ProductDTO getProductDTOById(String productId);
|
ProductDTO getProductDTOById(String productId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all data from persistence.
|
* Deletes all product data from persistence.
|
||||||
*/
|
*/
|
||||||
void clearData();
|
void clearProductData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,19 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.sqlite.SQLiteDataSource;
|
import org.sqlite.SQLiteDataSource;
|
||||||
|
|
||||||
import de.rwu.easydrop.api.dto.OfferDTO;
|
import de.rwu.easydrop.api.dto.OfferDTO;
|
||||||
import de.rwu.easydrop.api.dto.ProductDTO;
|
import de.rwu.easydrop.api.dto.ProductDTO;
|
||||||
|
import de.rwu.easydrop.api.dto.TransactionDTO;
|
||||||
import de.rwu.easydrop.exception.PersistenceException;
|
import de.rwu.easydrop.exception.PersistenceException;
|
||||||
import de.rwu.easydrop.model.Webshop;
|
import de.rwu.easydrop.model.Webshop;
|
||||||
|
import de.rwu.easydrop.util.FormattingUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows connecting to a SQLite Database.
|
* Allows connecting to a SQLite Database.
|
||||||
@@ -19,7 +25,18 @@ import de.rwu.easydrop.model.Webshop;
|
|||||||
* @since 0.2.0
|
* @since 0.2.0
|
||||||
*/
|
*/
|
||||||
public final class SQLiteConnector implements
|
public final class SQLiteConnector implements
|
||||||
ProductPersistenceInterface, OfferPersistenceInterface {
|
ProductPersistenceInterface, OfferPersistenceInterface,
|
||||||
|
TransactionPersistenceInterface {
|
||||||
|
/**
|
||||||
|
* Base for calculating percentages.
|
||||||
|
*/
|
||||||
|
private static final int PERCENT = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logging instance.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(SQLiteConnector.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQLite Database.
|
* SQLite Database.
|
||||||
*/
|
*/
|
||||||
@@ -41,6 +58,11 @@ public final class SQLiteConnector implements
|
|||||||
*/
|
*/
|
||||||
private static final String LAST_UPDATE_COL_NAME = "lastUpdate";
|
private static final String LAST_UPDATE_COL_NAME = "lastUpdate";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of 'offerId' column.
|
||||||
|
*/
|
||||||
|
private static final String OFFERID_COL_NAME = "offerId";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates instance.
|
* Creates instance.
|
||||||
*
|
*
|
||||||
@@ -89,6 +111,16 @@ public final class SQLiteConnector implements
|
|||||||
+ ")");
|
+ ")");
|
||||||
createOffers.close();
|
createOffers.close();
|
||||||
|
|
||||||
|
Statement createTransactions = connection.createStatement();
|
||||||
|
createTransactions.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS transactions ("
|
||||||
|
+ "offerId TEXT, "
|
||||||
|
+ "earnings REAL, "
|
||||||
|
+ "volume REAL, "
|
||||||
|
+ "transactionTime TEXT"
|
||||||
|
+ ")");
|
||||||
|
createTransactions.close();
|
||||||
|
|
||||||
// Close the connection
|
// Close the connection
|
||||||
connection.close();
|
connection.close();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@@ -105,7 +137,7 @@ public final class SQLiteConnector implements
|
|||||||
String query = "INSERT INTO products ("
|
String query = "INSERT INTO products ("
|
||||||
+ "dataOrigin, productId, currentPrice, merchant, "
|
+ "dataOrigin, productId, currentPrice, merchant, "
|
||||||
+ "deliveryPrice, available, lastUpdate"
|
+ "deliveryPrice, available, lastUpdate"
|
||||||
+ ") VALUES ("
|
+ ") VALUES ( "
|
||||||
+ "?, ?, ?, ?, ?, ?, ?"
|
+ "?, ?, ?, ?, ?, ?, ?"
|
||||||
+ ")";
|
+ ")";
|
||||||
|
|
||||||
@@ -123,7 +155,8 @@ public final class SQLiteConnector implements
|
|||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PersistenceException("Something went wrong while saving to SQLite", e);
|
throw new PersistenceException(
|
||||||
|
"Something went wrong while saving product to SQLite", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +189,8 @@ public final class SQLiteConnector implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PersistenceException("Something went wrong while reading from SQLite");
|
throw new PersistenceException(
|
||||||
|
"Something went wrong while reading product from SQLite");
|
||||||
}
|
}
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
@@ -168,16 +202,9 @@ public final class SQLiteConnector implements
|
|||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
public void clearData() {
|
public void clearData() {
|
||||||
try (Connection connection = db.getConnection();
|
clearProductData();
|
||||||
Statement statement = connection.createStatement()) {
|
clearOfferData();
|
||||||
|
clearTXData();
|
||||||
String productsQuery = "DELETE FROM products;";
|
|
||||||
String offersQuery = "DELETE FROM offers;";
|
|
||||||
statement.executeUpdate(productsQuery);
|
|
||||||
statement.executeUpdate(offersQuery);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new PersistenceException("Something went wrong while clearing the database", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -202,17 +229,18 @@ public final class SQLiteConnector implements
|
|||||||
ProductDTO targetProduct = dto.getTargetProduct();
|
ProductDTO targetProduct = dto.getTargetProduct();
|
||||||
|
|
||||||
statement.setString(++index, dto.getOfferId());
|
statement.setString(++index, dto.getOfferId());
|
||||||
statement.setString(++index, sourceProduct.getProductId());
|
|
||||||
statement.setString(++index, sourceProduct.getDataOrigin().toString());
|
statement.setString(++index, sourceProduct.getDataOrigin().toString());
|
||||||
|
statement.setString(++index, sourceProduct.getProductId());
|
||||||
statement.setDouble(++index, sourceProduct.getCurrentPrice());
|
statement.setDouble(++index, sourceProduct.getCurrentPrice());
|
||||||
statement.setString(++index, targetProduct.getProductId());
|
|
||||||
statement.setString(++index, targetProduct.getDataOrigin().toString());
|
statement.setString(++index, targetProduct.getDataOrigin().toString());
|
||||||
|
statement.setString(++index, targetProduct.getProductId());
|
||||||
statement.setDouble(++index, targetProduct.getCurrentPrice());
|
statement.setDouble(++index, targetProduct.getCurrentPrice());
|
||||||
statement.setString(++index, dto.getLastUpdate());
|
statement.setString(++index, dto.getLastUpdate());
|
||||||
|
|
||||||
statement.executeUpdate();
|
statement.executeUpdate();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PersistenceException("Something went wrong while saving to SQLite", e);
|
throw new PersistenceException(
|
||||||
|
"Something went wrong while saving offer to SQLite", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,24 +262,186 @@ public final class SQLiteConnector implements
|
|||||||
try (ResultSet resultSet = statement.executeQuery()) {
|
try (ResultSet resultSet = statement.executeQuery()) {
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
dto = new OfferDTO();
|
dto = new OfferDTO();
|
||||||
ProductDTO srcProduct = new ProductDTO(
|
ProductDTO srcProduct = getProductDTOById(resultSet.getString("sourceId"));
|
||||||
resultSet.getString("sourceId"),
|
ProductDTO targetProduct = getProductDTOById(resultSet.getString("targetId"));
|
||||||
Webshop.fromString(resultSet.getString("sourceWebshop")));
|
dto.setOfferId(resultSet.getString(OFFERID_COL_NAME));
|
||||||
srcProduct.setCurrentPrice(resultSet.getDouble("sourcePrice"));
|
|
||||||
ProductDTO targetProduct = new ProductDTO(
|
|
||||||
resultSet.getString("targetId"),
|
|
||||||
Webshop.fromString(resultSet.getString("targetWebshop")));
|
|
||||||
srcProduct.setCurrentPrice(resultSet.getDouble("targetPrice"));
|
|
||||||
dto.setOfferId(resultSet.getString("offerId"));
|
|
||||||
dto.setSourceProduct(srcProduct);
|
dto.setSourceProduct(srcProduct);
|
||||||
dto.setTargetProduct(targetProduct);
|
dto.setTargetProduct(targetProduct);
|
||||||
dto.setLastUpdate(resultSet.getString(LAST_UPDATE_COL_NAME));
|
dto.setLastUpdate(resultSet.getString(LAST_UPDATE_COL_NAME));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new PersistenceException("Something went wrong while reading from SQLite", e);
|
throw new PersistenceException(
|
||||||
|
"Something went wrong while reading offer from SQLite", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTX(final TransactionDTO dto) {
|
||||||
|
String query = "INSERT INTO transactions ("
|
||||||
|
+ "offerId, volume, earnings, transactionTime"
|
||||||
|
+ ") VALUES ("
|
||||||
|
+ "?, ?, ?, ?"
|
||||||
|
+ ")";
|
||||||
|
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
statement.setString(++index, dto.getOfferId());
|
||||||
|
statement.setDouble(++index, dto.getVolume());
|
||||||
|
statement.setDouble(++index, dto.getEarnings());
|
||||||
|
statement.setString(++index, dto.getTransactionTime());
|
||||||
|
|
||||||
|
statement.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException(
|
||||||
|
"Something went wrong while saving transaction to SQLite", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void outputTransactionsToLog() {
|
||||||
|
String query = "SELECT * FROM transactions t "
|
||||||
|
+ "LEFT JOIN offers o ON t.offerId = o.offerId "
|
||||||
|
+ "ORDER BY transactionTime ASC";
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int index = 0;
|
||||||
|
sb.append("Transaction History:");
|
||||||
|
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
|
|
||||||
|
try (ResultSet resultSet = statement.executeQuery()) {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
sb.append("\n");
|
||||||
|
sb.append(String.format("%3d", ++index));
|
||||||
|
sb.append(String.format(" - %s - ", resultSet.getString("transactionTime")));
|
||||||
|
sb.append(String.format("+%s (%s) - %s",
|
||||||
|
FormattingUtil.formatEuro(resultSet.getDouble("earnings")),
|
||||||
|
FormattingUtil.formatEuro(resultSet.getDouble("volume")),
|
||||||
|
resultSet.getString(OFFERID_COL_NAME)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException(
|
||||||
|
"Something went wrong while reading transaction from SQLite", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
String logString = sb.toString();
|
||||||
|
LOGGER.info(logString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void outputSummaryToLog() {
|
||||||
|
String query = "SELECT SUM(earnings) AS earnings, SUM(volume) AS volume FROM transactions;";
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Summary:\n");
|
||||||
|
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
|
|
||||||
|
try (ResultSet resultSet = statement.executeQuery()) {
|
||||||
|
if (resultSet.next()) {
|
||||||
|
double earnings = resultSet.getDouble("earnings");
|
||||||
|
double volume = resultSet.getDouble("volume");
|
||||||
|
String avgMargin = String.valueOf(
|
||||||
|
Math.round(earnings / volume * PERCENT)) + "%";
|
||||||
|
|
||||||
|
String earningsFormatted = FormattingUtil.formatEuro(earnings);
|
||||||
|
String volumeFormatted = FormattingUtil.formatEuro(volume);
|
||||||
|
|
||||||
|
sb.append(String.format("Total earnings: %s, ", earningsFormatted));
|
||||||
|
sb.append(String.format("total volume: %s ", volumeFormatted));
|
||||||
|
sb.append(String.format("(average margin %s)", avgMargin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException(
|
||||||
|
"Something went wrong while reading transaction summary from SQLite", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
String logString = sb.toString();
|
||||||
|
LOGGER.info(logString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearTXData() {
|
||||||
|
flushTable("transactions");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearOfferData() {
|
||||||
|
flushTable("offers");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearProductData() {
|
||||||
|
flushTable("products");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flushes all data from the specified table.
|
||||||
|
*
|
||||||
|
* @param table
|
||||||
|
*/
|
||||||
|
private void flushTable(final String table) {
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
Statement statement = connection.createStatement()) {
|
||||||
|
if (table.matches("[\\w]+")) {
|
||||||
|
String query = "DELETE FROM " + table + ";";
|
||||||
|
statement.executeUpdate(query);
|
||||||
|
} else {
|
||||||
|
throw new PersistenceException("Table name contains illegal characters");
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException("Something went wrong while clearing the database", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteOfferById(final String offerId) {
|
||||||
|
String query = "DELETE FROM offers WHERE offerID = ?;";
|
||||||
|
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
|
statement.setString(1, offerId);
|
||||||
|
|
||||||
|
statement.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException(
|
||||||
|
"Something went wrong while deleting offer from SQLite", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<OfferDTO> getOffers() {
|
||||||
|
List<OfferDTO> list = new ArrayList<>();
|
||||||
|
String query = "SELECT * FROM offers";
|
||||||
|
|
||||||
|
try (Connection connection = db.getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
|
|
||||||
|
try (ResultSet resultSet = statement.executeQuery()) {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
OfferDTO dto = new OfferDTO();
|
||||||
|
ProductDTO srcProduct = getProductDTOById(resultSet.getString("sourceId"));
|
||||||
|
ProductDTO targetProduct = getProductDTOById(resultSet.getString("targetId"));
|
||||||
|
dto.setOfferId(resultSet.getString(OFFERID_COL_NAME));
|
||||||
|
dto.setSourceProduct(srcProduct);
|
||||||
|
dto.setTargetProduct(targetProduct);
|
||||||
|
dto.setLastUpdate(resultSet.getString(LAST_UPDATE_COL_NAME));
|
||||||
|
|
||||||
|
list.add(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new PersistenceException(
|
||||||
|
"Something went wrong while reading offers from SQLite", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package de.rwu.easydrop.data.connector;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.TransactionDTO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persistence interface for transactions.
|
||||||
|
*
|
||||||
|
* @since 0.3.0
|
||||||
|
*/
|
||||||
|
public interface TransactionPersistenceInterface {
|
||||||
|
/**
|
||||||
|
* Writes a ProductDTO to persistence.
|
||||||
|
*
|
||||||
|
* @param dto
|
||||||
|
*/
|
||||||
|
void writeTX(TransactionDTO dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes transactions to log.
|
||||||
|
*/
|
||||||
|
void outputTransactionsToLog();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes transaction summary (total volume and earnings) to log.
|
||||||
|
*/
|
||||||
|
void outputSummaryToLog();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all transaction data from persistence.
|
||||||
|
*/
|
||||||
|
void clearTXData();
|
||||||
|
}
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
package de.rwu.easydrop.exception;
|
package de.rwu.easydrop.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception that signifies the data of an Offer are invalid.
|
||||||
|
*
|
||||||
|
* @since 0.3.0
|
||||||
|
*/
|
||||||
public class InvalidOfferException extends RuntimeException {
|
public class InvalidOfferException extends RuntimeException {
|
||||||
/**
|
/**
|
||||||
* Throws an exception that signifies the data of an Offer are invalid.
|
* Throws an exception that signifies the data of an Offer are invalid.
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package de.rwu.easydrop.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception that signifies the data of a Transaction are invalid.
|
||||||
|
*
|
||||||
|
* @since 0.3.0
|
||||||
|
*/
|
||||||
|
public class InvalidTransactionException extends RuntimeException {
|
||||||
|
/**
|
||||||
|
* Throws an exception that signifies the data of an Offer are invalid.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public InvalidTransactionException(final String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception that signifies the data of an Offer are invalid.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* @param cause
|
||||||
|
*/
|
||||||
|
public InvalidTransactionException(final String message, final Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package de.rwu.easydrop.service.processing;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.TransactionDTO;
|
||||||
|
import de.rwu.easydrop.data.connector.TransactionPersistenceInterface;
|
||||||
|
import de.rwu.easydrop.model.Offer;
|
||||||
|
import de.rwu.easydrop.model.Transaction;
|
||||||
|
import de.rwu.easydrop.service.mapping.TransactionMapper;
|
||||||
|
import de.rwu.easydrop.util.Timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles transactions.
|
||||||
|
*
|
||||||
|
* @since 0.3.0
|
||||||
|
*/
|
||||||
|
public class TransactionHandler {
|
||||||
|
/**
|
||||||
|
* Transaction persistence.
|
||||||
|
*/
|
||||||
|
private TransactionPersistenceInterface txPersistence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new transaction handler.
|
||||||
|
*
|
||||||
|
* @param txdb transaction persistence
|
||||||
|
*/
|
||||||
|
public TransactionHandler(final TransactionPersistenceInterface txdb) {
|
||||||
|
this.txPersistence = txdb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates transaction from offer.
|
||||||
|
*
|
||||||
|
* @param offer Offer
|
||||||
|
*/
|
||||||
|
public void turnOfferToTransaction(final Offer offer) {
|
||||||
|
Transaction tx = new Transaction();
|
||||||
|
tx.setOfferId(offer.getOfferId());
|
||||||
|
tx.setVolume(offer.getTargetProduct().getCurrentPrice());
|
||||||
|
tx.setEarnings(offer.getTargetProduct().getCurrentPrice()
|
||||||
|
- offer.getSourceProduct().getCurrentPrice());
|
||||||
|
tx.setTransactionTime(Timestamp.now());
|
||||||
|
|
||||||
|
// Write transaction to persistence
|
||||||
|
TransactionDTO txDTO = TransactionMapper.mapTXToDTO(tx);
|
||||||
|
txPersistence.writeTX(txDTO);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package de.rwu.easydrop.service.validation;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.exception.InvalidTransactionException;
|
||||||
|
import de.rwu.easydrop.model.Transaction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates transactions.
|
||||||
|
*
|
||||||
|
* @since 0.3.0
|
||||||
|
*/
|
||||||
|
public final class TransactionValidator {
|
||||||
|
/**
|
||||||
|
* Private constructor to prevent unwanted instantiation.
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
|
*/
|
||||||
|
private TransactionValidator() throws UnsupportedOperationException {
|
||||||
|
throw new UnsupportedOperationException("This is a validator class, don't instantiate it.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes sure a transaction does not contain invalid information.
|
||||||
|
*
|
||||||
|
* @param tx the Transaction
|
||||||
|
*/
|
||||||
|
public static void validate(final Transaction tx) {
|
||||||
|
try {
|
||||||
|
if (tx.getOfferId().equals("")) {
|
||||||
|
throw new InvalidTransactionException("Offer ID cannot be empty");
|
||||||
|
}
|
||||||
|
if (tx.getEarnings() == 0) {
|
||||||
|
throw new InvalidTransactionException("Earnings can't be zero");
|
||||||
|
}
|
||||||
|
if (tx.getVolume() == 0) {
|
||||||
|
throw new InvalidTransactionException("Volume can't be zero");
|
||||||
|
}
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
throw new InvalidTransactionException(
|
||||||
|
"Required information is missing in the transaction", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package de.rwu.easydrop.service.writer;
|
||||||
|
|
||||||
|
import de.rwu.easydrop.api.dto.TransactionDTO;
|
||||||
|
import de.rwu.easydrop.data.connector.TransactionPersistenceInterface;
|
||||||
|
import de.rwu.easydrop.model.Transaction;
|
||||||
|
import de.rwu.easydrop.service.mapping.TransactionMapper;
|
||||||
|
import de.rwu.easydrop.service.validation.TransactionValidator;
|
||||||
|
|
||||||
|
public class TransactionWriter {
|
||||||
|
/**
|
||||||
|
* Persistence.
|
||||||
|
*/
|
||||||
|
private TransactionPersistenceInterface persistence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param newPersistence the persistence to set
|
||||||
|
*/
|
||||||
|
public TransactionWriter(final TransactionPersistenceInterface newPersistence) {
|
||||||
|
this.persistence = newPersistence;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates and saves a transaction to persistence.
|
||||||
|
*
|
||||||
|
* @param tx Transaction
|
||||||
|
*/
|
||||||
|
public void writeTXToPersistence(final Transaction tx) {
|
||||||
|
TransactionDTO dto = TransactionMapper.mapTXToDTO(tx);
|
||||||
|
TransactionValidator.validate(tx);
|
||||||
|
|
||||||
|
persistence.writeTX(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user