diff --git a/conf/nodes.xml b/conf/nodes.xml
index c1de579..e327af1 100644
--- a/conf/nodes.xml
+++ b/conf/nodes.xml
@@ -13,7 +13,7 @@
MEAT PURCHASE;VEGETABLE PURCHASE;FRUIT PURCHASE
- 5
+ 10
MEAT SALE_AND_PURCHASE;VEGETABLE SALE_AND_PURCHASE;FRUIT SALE_AND_PURCHASE
diff --git a/conf/scenarios.xml b/conf/scenarios.xml
index b5434a5..68f28ef 100644
--- a/conf/scenarios.xml
+++ b/conf/scenarios.xml
@@ -6,18 +6,19 @@
type CDATA #REQUIRED>
]>
+
generate
- generate
- generate
- generate
- generate
- generate
- generate
- generate
- generate
+ sendreq SALE FRUIT jablko
\ No newline at end of file
diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/channel/ChannelBase.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/channel/ChannelBase.java
index a79add1..0f0b984 100644
--- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/channel/ChannelBase.java
+++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/channel/ChannelBase.java
@@ -1,5 +1,6 @@
package cz.cvut.fel.sit.omo.foodchain.channel;
+import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.operation.Transaction;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
import cz.cvut.fel.sit.omo.foodchain.requirement.Requirement;
@@ -32,9 +33,9 @@ public abstract class ChannelBase implements Observable {
this.productType = ProductType.OTHER;
}
- public Queue getTransactions()
+ public Queue getTransactions(NodeBase node)
{
- return this.transactions;
+ return this.transactions.stream().filter(t -> t.getNodeReceiver().equals(node)).collect(Collectors.toCollection(LinkedList::new));
}
public Queue getCurrentRequirements()
diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/factory/ScenarioFactory.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/factory/ScenarioFactory.java
index 5282eb9..d52163b 100644
--- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/factory/ScenarioFactory.java
+++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/factory/ScenarioFactory.java
@@ -60,8 +60,11 @@ public class ScenarioFactory
scenarioStep = new DoActionStep(node, ProductOperationType.valueOf(parts[1]), p);
}
break;
- case "sendreq":
- scenarioStep = new SendRequirementStep(node, TransactionType.valueOf(parts[1]), ProductType.valueOf(parts[2]), parts[3], Double.parseDouble(parts[4]));
+ case "sell":
+ scenarioStep = new SendRequirementStep(node, TransactionType.SALE, ProductType.valueOf(parts[1]), parts[2], Double.parseDouble(parts[3]));
+ break;
+ case "buy":
+ scenarioStep = new SendRequirementStep(node, TransactionType.PURCHASE, ProductType.valueOf(parts[1]), parts[2]);
break;
case "pass":
scenarioStep = new PassStep();
@@ -75,10 +78,6 @@ public class ScenarioFactory
{
System.err.println("! Wrong type of enum in ScenarioFactory: " + e);
}
- catch (Exception e)
- {
- System.err.println("! Fatal error in ScenarioFactory: " + e);
- }
return s;
}
diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/base/NodeBase.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/base/NodeBase.java
index 73e8b9a..7490577 100644
--- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/base/NodeBase.java
+++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/base/NodeBase.java
@@ -14,6 +14,7 @@ import cz.cvut.fel.sit.omo.foodchain.util.ChannelObserver;
import org.javamoney.moneta.Money;
import javax.money.MonetaryAmount;
+import javax.naming.InsufficientResourcesException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -25,7 +26,7 @@ public class NodeBase implements ChannelObserver {
private final List products;
private final List refusedTransactions;
- private final MonetaryAmount money;
+ private MonetaryAmount money;
protected NodeType allowedSeller;
protected NodeType allowedPurchaser;
@@ -45,42 +46,64 @@ public class NodeBase implements ChannelObserver {
public void sendTransaction(Product product, NodeBase node) {
- Transaction transaction = new ProductTransaction(this, node, TransactionType.SALE, product);
-
- subscribedChannels.keySet().stream()
- .filter(ch -> ch.getProductType().equals(product.getProductType()))
- .findAny().ifPresent(channel -> channel.addTransaction(transaction));
+ try {
+ Transaction transaction = new ProductTransaction(this, node, TransactionType.SALE, product);
+ subscribedChannels.keySet().stream()
+ .filter(ch -> ch.getProductType().equals(product.getProductType()))
+ .findAny().ifPresent(channel -> channel.addTransaction(transaction));
+ } catch (InsufficientResourcesException e) {
+ e.printStackTrace();
+ }
}
public void sendTransaction(MonetaryAmount amount, NodeBase node, ProductTransaction prevTransaction) {
- Transaction transaction = new FinancialTransaction(this, node, TransactionType.PURCHASE, amount, prevTransaction);
-
- subscribedChannels.keySet().stream()
- .filter(ch -> ch.getProductType().equals(prevTransaction.getProduct().getProductType()))
- .findAny().ifPresent(channel -> channel.addTransaction(transaction));
+ try {
+ Transaction transaction = new FinancialTransaction(this, node, TransactionType.PURCHASE, amount, prevTransaction);
+ subscribedChannels.keySet().stream()
+ .filter(ch -> ch.getProductType().equals(prevTransaction.getProduct().getProductType()))
+ .findAny().ifPresent(channel -> channel.addTransaction(transaction));
+ } catch (InsufficientResourcesException e) {
+ e.printStackTrace();
+ }
}
+ public void receiveTransaction(Transaction transaction) {
+ try {
+ receiveTransaction((ProductTransaction) transaction);
+ }
+ catch (Exception e) {
+ try {
+ receiveTransaction((FinancialTransaction) transaction);
+ }
+ catch (Exception ex) {
+ System.err.println(ex.getMessage());
+ }
+ }
+ }
public void receiveTransaction(ProductTransaction transaction) {
+ if (validateSignature(transaction)) {
+ transaction.endTransaction();
+ sendTransaction(transaction.getProduct().getPrice(), transaction.getNodeCreator(), transaction);
+ }
+ else refuseTransaction(transaction);
}
-
public void receiveTransaction(FinancialTransaction transaction) {
-
+ if (validateSignature(transaction)) transaction.endTransaction();
+ else refuseTransaction(transaction);
}
public void refuseTransaction(Transaction transaction) {
transaction.endTransaction();
- refusedTransactions.add(transaction); //TODO maybe need more work on it
+ refusedTransactions.add(transaction);
}
- public Transaction readNextTransaction(ChannelBase channel) {
- //TODO
- return null;
-// return channel.getNextTransaction();
+ public void receiveTransactions() {
+ subscribedChannels.keySet().forEach(ch -> ch.getTransactions(this).forEach(t -> {receiveTransaction(t); ch.disposeOf(t);}));
}
@@ -153,7 +176,11 @@ public class NodeBase implements ChannelObserver {
}
public void addMoney(MonetaryAmount m) {
- this.money.add(m);
+ this.money = this.money.add(m);
+ }
+
+ public void subtractMoney(MonetaryAmount m) {
+ this.money = this.money.subtract(m);
}
public boolean validateSignature(Transaction transaction) {
@@ -194,4 +221,9 @@ public class NodeBase implements ChannelObserver {
acceptRequirement(requirement);
}
}
+
+ public void tick() {
+ receiveTransactions();
+ System.out.println(this.getClass().getSimpleName() + ": " + money.getNumber());
+ }
}
diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/FinancialTransaction.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/FinancialTransaction.java
index 4be879b..bbcc732 100644
--- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/FinancialTransaction.java
+++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/FinancialTransaction.java
@@ -3,17 +3,20 @@ package cz.cvut.fel.sit.omo.foodchain.operation;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import javax.money.MonetaryAmount;
+import javax.naming.InsufficientResourcesException;
public class FinancialTransaction extends Transaction {
private final MonetaryAmount amount;
private final ProductTransaction transactionPaid;
- public FinancialTransaction(NodeBase creator, NodeBase receiver, TransactionType type, MonetaryAmount amount, ProductTransaction transactionPaid) {
+ public FinancialTransaction(NodeBase creator, NodeBase receiver, TransactionType type, MonetaryAmount amount, ProductTransaction transactionPaid) throws InsufficientResourcesException {
super(creator, receiver, type);
this.amount = amount;
this.transactionPaid = transactionPaid;
- creator.addMoney(amount.negate());
+ if (creator.getMoney().isLessThan(amount)) throw new InsufficientResourcesException("not enough money");
+ creator.subtractMoney(amount);
+ System.out.println(toString());
}
@Override
@@ -29,4 +32,12 @@ public class FinancialTransaction extends Transaction {
public ProductTransaction getTransactionPaid() {
return transactionPaid;
}
+
+ @Override
+ public String toString() {
+ return "FinancialTransaction{" +
+ "amount=" + amount.getNumber() +
+ ", transactionPaid=" + transactionPaid +
+ '}';
+ }
}
diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/ProductTransaction.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/ProductTransaction.java
index 58966de..640ca63 100644
--- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/ProductTransaction.java
+++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/ProductTransaction.java
@@ -2,6 +2,9 @@ package cz.cvut.fel.sit.omo.foodchain.operation;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.product.Product;
+import cz.cvut.fel.sit.omo.foodchain.product.ProductState;
+
+import javax.naming.InsufficientResourcesException;
public class ProductTransaction extends Transaction {
@@ -9,19 +12,22 @@ public class ProductTransaction extends Transaction {
private final Product product;
private final ProductOperationType type;
- public ProductTransaction(NodeBase creator, NodeBase receiver, TransactionType transactionType, Product product) {
+ public ProductTransaction(NodeBase creator, NodeBase receiver, TransactionType transactionType, Product product) throws InsufficientResourcesException {
super(creator, receiver, transactionType);
this.product = product;
type = null;
lastOperation = product.getCurrentOperation();
+ if (product == null || product.getProductState() != ProductState.AVAILABLE) throw new InsufficientResourcesException("product not available");
product.setCurrentOperation(this);
product.setStateToReadyForDispatch();
+ creator.getStorage().remove(product);
System.out.println(toString());
}
@Override
public void endTransaction() {
super.endTransaction();
+ getNodeReceiver().storeProduct(product);
product.setStateToAvailable();
}
diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/requirement/Requirement.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/requirement/Requirement.java
index 44f0f20..5e513cf 100644
--- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/requirement/Requirement.java
+++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/requirement/Requirement.java
@@ -2,10 +2,12 @@ package cz.cvut.fel.sit.omo.foodchain.requirement;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.operation.TransactionType;
+import cz.cvut.fel.sit.omo.foodchain.product.ProductState;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
import org.javamoney.moneta.Money;
import javax.money.MonetaryAmount;
+import javax.naming.InsufficientResourcesException;
public class Requirement {
diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/scenario/SendRequirementStep.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/scenario/SendRequirementStep.java
index c7bc813..862cc42 100644
--- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/scenario/SendRequirementStep.java
+++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/scenario/SendRequirementStep.java
@@ -3,20 +3,31 @@ package cz.cvut.fel.sit.omo.foodchain.scenario;
import cz.cvut.fel.sit.omo.foodchain.node.base.NodeBase;
import cz.cvut.fel.sit.omo.foodchain.operation.TransactionType;
import cz.cvut.fel.sit.omo.foodchain.product.ProductType;
+import org.javamoney.moneta.Money;
+
+import javax.money.MonetaryAmount;
public class SendRequirementStep extends ScenarioStep {
private final NodeBase node;
private final TransactionType tType;
private final ProductType pType;
private final String pName;
- private final double pPrice;
+ private final MonetaryAmount pPrice;
- public SendRequirementStep(NodeBase node, TransactionType tType, ProductType pType, String pName, double pPrice) {
+ public SendRequirementStep(NodeBase node, TransactionType tType, ProductType pType, String pName) {
this.node = node;
this.tType = tType;
this.pType = pType;
this.pName = pName;
- this.pPrice = pPrice;
+ this.pPrice = Money.of(0, "USD");
+ }
+
+ public SendRequirementStep(NodeBase node, TransactionType tType, ProductType pType, String pName, Double price) {
+ this.node = node;
+ this.tType = tType;
+ this.pType = pType;
+ this.pName = pName;
+ this.pPrice = Money.of(price, "USD");
}
@Override
diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/util/Ticker.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/util/Ticker.java
index 7fbf1c6..7ccf9b7 100644
--- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/util/Ticker.java
+++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/util/Ticker.java
@@ -14,12 +14,12 @@ public class Ticker {
public static void start() {
timer = new Timer(500, actionEvent -> {
- System.out.println("tick");
+ System.out.println("-----tick-----");
PoolDatabase db = FoodChain.getFactoryManager().getPoolDatabaseInstance();
boolean productBool = db.getProductPoolInstance().findAll().stream().filter(Product::tick).count() == 0; // change duration of action
boolean scenarioBool = db.getScenarioPoolInstance().findAll().stream().filter(Scenario::tick).count() == 0; // do next step in scenario
boolean channelBool = db.getChannelPoolInstance().findAll().stream().filter(ChannelBase::tick).count() == 0; // change TTL of requirements
-// db.getNodePoolInstance().findAll().forEach(n -> n.tick()); // maybe unnecessary
+ db.getNodePoolInstance().findAll().forEach(n -> n.tick()); // receive transactions
if (channelBool && productBool && scenarioBool) stop();
});
timer.start();