diff --git a/conf/nodes.xml b/conf/nodes.xml index 7f80ca2..c1de579 100644 --- a/conf/nodes.xml +++ b/conf/nodes.xml @@ -13,7 +13,7 @@ MEAT PURCHASE;VEGETABLE PURCHASE;FRUIT PURCHASE - 0 + 5 MEAT SALE_AND_PURCHASE;VEGETABLE SALE_AND_PURCHASE;FRUIT SALE_AND_PURCHASE diff --git a/conf/scenarios.xml b/conf/scenarios.xml index 5ab9512..b5434a5 100644 --- a/conf/scenarios.xml +++ b/conf/scenarios.xml @@ -20,10 +20,4 @@ generate - - - pass - sendreq PURCHASE FRUIT jablko - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index e2b91a2..4da069c 100644 --- a/pom.xml +++ b/pom.xml @@ -17,8 +17,8 @@ - 14 - 14 + 12 + 12 \ 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 4860f9c..a79add1 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 @@ -60,7 +60,7 @@ public abstract class ChannelBase implements Observable { @Override public void notifyAllObservers(){ - subscribers.forEach(subscriber -> requirements.forEach(subscriber::update)); + subscribers.forEach(subscriber -> new LinkedList<>(requirements).forEach(r -> subscriber.update(r, this))); } @Override @@ -82,6 +82,10 @@ public abstract class ChannelBase implements Observable { this.transactions.add(transaction); } + public void disposeOf(Requirement requirement) { this.requirements.remove(requirement); } + + public void disposeOf(Transaction transaction) { this.transactions.remove(transaction); } + /** * Clears all requirements from this channel */ 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 b4dc5cd..5282eb9 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 @@ -61,7 +61,7 @@ public class ScenarioFactory } break; case "sendreq": - scenarioStep = new SendRequirementStep(node, TransactionType.valueOf(parts[1]), ProductType.valueOf(parts[2]), parts[3]); + scenarioStep = new SendRequirementStep(node, TransactionType.valueOf(parts[1]), ProductType.valueOf(parts[2]), parts[3], Double.parseDouble(parts[4])); break; case "pass": scenarioStep = new PassStep(); diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/Farmer.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/Farmer.java index 9234d06..c65ffcf 100644 --- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/Farmer.java +++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/node/Farmer.java @@ -15,6 +15,6 @@ public class Farmer extends SellerNodeBase { public void generateProduct(Product product) { storeProduct(product); - createRequirement(TransactionType.SALE, product.getProductType(), product.getName()); + createRequirement(TransactionType.SALE, product.getProductType(), product.getName(), product.getPrice()); } } 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 0ec5ab7..73e8b9a 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 @@ -5,6 +5,7 @@ import cz.cvut.fel.sit.omo.foodchain.channel.ChannelSubscriptionType; import cz.cvut.fel.sit.omo.foodchain.node.enums.NodeType; import cz.cvut.fel.sit.omo.foodchain.operation.*; import cz.cvut.fel.sit.omo.foodchain.product.Product; +import cz.cvut.fel.sit.omo.foodchain.product.ProductState; import cz.cvut.fel.sit.omo.foodchain.product.ProductType; import cz.cvut.fel.sit.omo.foodchain.requirement.Requirement; import cz.cvut.fel.sit.omo.foodchain.signature.Signature; @@ -83,15 +84,28 @@ public class NodeBase implements ChannelObserver { } - public void createRequirement(TransactionType tType, ProductType pType, String pName) { - Requirement req = new Requirement(this, tType, pType, pName); + public void createRequirement(TransactionType tType, ProductType pType, String pName, double price) { + Requirement req = new Requirement(this, tType, pType, pName, price); subscribedChannels.keySet().stream() .filter(ch -> ch.getProductType().equals(pType)) .findAny().ifPresent(channel -> channel.addRequirement(req)); } - public void acceptRequirement(Requirement requirement) { - System.out.println(this.getClass().getSimpleName() + " accepted " + requirement.toString()); + public void createRequirement(TransactionType tType, ProductType pType, String pName, MonetaryAmount price) { + Requirement req = new Requirement(this, tType, pType, pName, price); + subscribedChannels.keySet().stream() + .filter(ch -> ch.getProductType().equals(pType)) + .findAny().ifPresent(channel -> channel.addRequirement(req)); + } + + public void acceptRequirement(Requirement req) { + System.out.println(this.getClass().getSimpleName() + " accepted " + req.toString()); + if (req.getTransactionType() == TransactionType.SALE) { + createRequirement(TransactionType.PURCHASE, req.getProductType(), req.getProductName(), req.getPrice()); + } + else { + sendTransaction(getProductFromStorage(req.getProductName(), req.getProductType()), req.getCreator()); + } } @@ -134,10 +148,13 @@ public class NodeBase implements ChannelObserver { return products; } - public Signature generateSignature(Transaction transaction) { - return SignatureManager.signTransaction(transaction); + public MonetaryAmount getMoney() { + return money; } + public void addMoney(MonetaryAmount m) { + this.money.add(m); + } public boolean validateSignature(Transaction transaction) { return SignatureManager.validateSignature(transaction); @@ -151,9 +168,30 @@ public class NodeBase implements ChannelObserver { ((allowedPurchaser == NodeType.valueOf(simpleName) || allowedPurchaser == NodeType.All) && req.getTransactionType() == TransactionType.PURCHASE)); } + boolean transactionSubscriptionCheck(Requirement requirement, ChannelBase channel) { + switch (subscribedChannels.get(channel)) { + case SALE: + return requirement.getTransactionType() == TransactionType.SALE; + case PURCHASE: + return requirement.getTransactionType() == TransactionType.PURCHASE; + case SALE_AND_PURCHASE: + return true; + + } + return false; + } + + boolean requirementCheck(Requirement req) { + return (req.getTransactionType() == TransactionType.SALE && money.isGreaterThanOrEqualTo(req.getPrice())) || + (req.getTransactionType() == TransactionType.PURCHASE && getProductFromStorage(req.getProductName(), req.getProductType()) != null && + getProductFromStorage(req.getProductName(), req.getProductType()).getProductState() == ProductState.AVAILABLE); + } + @Override - public void update(Requirement requirement) { - if (senderPurchaserCheck(requirement)) + public void update(Requirement requirement, ChannelBase channel) { + if (senderPurchaserCheck(requirement) && transactionSubscriptionCheck(requirement, channel) && requirementCheck(requirement)) { + channel.disposeOf(requirement); acceptRequirement(requirement); + } } } 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 1c2b20a..4be879b 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 @@ -13,6 +13,13 @@ public class FinancialTransaction extends Transaction { super(creator, receiver, type); this.amount = amount; this.transactionPaid = transactionPaid; + creator.addMoney(amount.negate()); + } + + @Override + public void endTransaction() { + super.endTransaction(); + getNodeReceiver().addMoney(amount); } public MonetaryAmount getAmount() { 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 6539950..58966de 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 @@ -16,6 +16,7 @@ public class ProductTransaction extends Transaction { lastOperation = product.getCurrentOperation(); product.setCurrentOperation(this); product.setStateToReadyForDispatch(); + System.out.println(toString()); } @Override @@ -35,4 +36,11 @@ public class ProductTransaction extends Transaction { public ProductOperationType getType() { return type; } + + @Override + public String toString() { + return "ProductTransaction{" + + "product=" + product.getName() + + '}'; + } } diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/Transaction.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/Transaction.java index 5c7dd46..2deba2a 100644 --- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/Transaction.java +++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/operation/Transaction.java @@ -15,7 +15,6 @@ public abstract class Transaction extends OperationBase { transactionType = type; nodeReceiver = receiver; signature = SignatureManager.signTransaction(this); - System.out.println(toString()); } public void endTransaction() { diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/Product.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/Product.java index e09d225..b60b3cc 100644 --- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/Product.java +++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/product/Product.java @@ -12,7 +12,7 @@ public class Product private ProductState productState; private ProductType productType; private OperationBase currentOperation; - private MonetaryAmount money; + private MonetaryAmount price; private String name; @@ -26,7 +26,7 @@ public class Product this.name = name; this.productType = productType; this.productState = ProductState.AVAILABLE; - this.money = Money.of(0, "USD"); + this.price = Money.of(0, "USD"); } public Product(String name, ProductType productType, double m) @@ -34,7 +34,7 @@ public class Product this.name = name; this.productType = productType; this.productState = ProductState.AVAILABLE; - this.money = Money.of(m, "USD"); + this.price = Money.of(m, "USD"); } /** @@ -48,7 +48,7 @@ public class Product this.name = name; this.productType = productType; this.productState = productState; - this.money = Money.of(0, "USD"); + this.price = Money.of(0, "USD"); } public Product(String name, ProductType productType, ProductState productState, double m) @@ -56,7 +56,7 @@ public class Product this.name = name; this.productType = productType; this.productState = productState; - this.money = Money.of(m, "USD"); + this.price = Money.of(m, "USD"); } public boolean tick() { @@ -155,7 +155,7 @@ public class Product this.currentOperation = currentOperation; } - public MonetaryAmount getMoney() { return money; } + public MonetaryAmount getPrice() { return price; } - public void setMoney(MonetaryAmount money) { this.money = money; } + public void setPrice(MonetaryAmount price) { this.price = price; } } 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 5c50c13..44f0f20 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 @@ -3,6 +3,9 @@ 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.ProductType; +import org.javamoney.moneta.Money; + +import javax.money.MonetaryAmount; public class Requirement { @@ -10,13 +13,25 @@ public class Requirement { private final TransactionType transactionType; private final ProductType productType; private final String productName; + private final MonetaryAmount price; private int TTL; - public Requirement(NodeBase creator, TransactionType transactionType, ProductType productType, String productName) { + public Requirement(NodeBase creator, TransactionType transactionType, ProductType productType, String productName, double price) { this.creator = creator; this.transactionType = transactionType; this.productType = productType; this.productName = productName; + this.price = Money.of(price, "USD"); + TTL = 3; + System.out.println(toString()); + } + + public Requirement(NodeBase creator, TransactionType transactionType, ProductType productType, String productName, MonetaryAmount price) { + this.creator = creator; + this.transactionType = transactionType; + this.productType = productType; + this.productName = productName; + this.price = price; TTL = 3; System.out.println(toString()); } @@ -41,6 +56,8 @@ public class Requirement { return productName; } + public MonetaryAmount getPrice() { return price; } + public int getTTL() { return TTL; } @@ -50,7 +67,6 @@ public class Requirement { return "Requirement{" + "creator=" + creator.getClass().getSimpleName() + ", transactionType=" + transactionType + - ", productType=" + productType + ", productName='" + productName + '\'' + ", TTL=" + TTL + '}'; 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 1542449..c7bc813 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 @@ -9,16 +9,18 @@ public class SendRequirementStep extends ScenarioStep { private final TransactionType tType; private final ProductType pType; private final String pName; + private final double pPrice; - public SendRequirementStep(NodeBase node, TransactionType tType, ProductType pType, String pName) { + public SendRequirementStep(NodeBase node, TransactionType tType, ProductType pType, String pName, double pPrice) { this.node = node; this.tType = tType; this.pType = pType; this.pName = pName; + this.pPrice = pPrice; } @Override void execute() { - node.createRequirement(tType, pType, pName); + node.createRequirement(tType, pType, pName, pPrice); } } diff --git a/src/main/java/cz/cvut/fel/sit/omo/foodchain/util/ChannelObserver.java b/src/main/java/cz/cvut/fel/sit/omo/foodchain/util/ChannelObserver.java index 7111944..d4d7dc4 100644 --- a/src/main/java/cz/cvut/fel/sit/omo/foodchain/util/ChannelObserver.java +++ b/src/main/java/cz/cvut/fel/sit/omo/foodchain/util/ChannelObserver.java @@ -1,7 +1,8 @@ package cz.cvut.fel.sit.omo.foodchain.util; +import cz.cvut.fel.sit.omo.foodchain.channel.ChannelBase; import cz.cvut.fel.sit.omo.foodchain.requirement.Requirement; public interface ChannelObserver { - void update(Requirement requirement); + void update(Requirement requirement, ChannelBase channel); }