From f85f20d907dd4329e725e672f45c12b72adf185a Mon Sep 17 00:00:00 2001 From: Luca Keidel <info@lucakeidel.de> Date: Wed, 8 Jun 2016 10:17:48 +0200 Subject: [PATCH] Fixed wallet and server GUI --- .gitignore | 2 + src/fucoin/AbstractWallet.java | 6 +- src/fucoin/Main.java | 3 +- src/fucoin/Wallet.java | 332 ++++++++-------- src/fucoin/actions/join/ActionJoinAnswer.java | 2 +- .../persist/ActionSearchMyWalletAnswer.java | 2 +- ...tionCommitDistributedCommitedTransfer.java | 101 ++--- .../actions/transaction/ActionGetAmount.java | 2 +- .../transaction/ActionInvokeSentMoney2.java | 22 -- ...ionPrepareDistributedCommitedTransfer.java | 45 +-- ...pareDistributedCommitedTransferAnswer.java | 1 + .../transaction/ActionReceiveTransaction.java | 2 +- src/fucoin/gui/IWalletGuiControle.java | 1 + src/fucoin/gui/LogMessage.java | 26 ++ src/fucoin/gui/WalletGui.java | 355 ++++++++++-------- src/fucoin/supervisor/AmountTableModel.java | 36 +- src/fucoin/supervisor/SuperVisor.java | 162 ++++---- 17 files changed, 605 insertions(+), 495 deletions(-) delete mode 100644 src/fucoin/actions/transaction/ActionInvokeSentMoney2.java create mode 100644 src/fucoin/gui/LogMessage.java diff --git a/.gitignore b/.gitignore index 09e3bc9..917f1dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /bin/ /target/ +.idea/ +*.iml diff --git a/src/fucoin/AbstractWallet.java b/src/fucoin/AbstractWallet.java index e77b674..076a8f2 100644 --- a/src/fucoin/AbstractWallet.java +++ b/src/fucoin/AbstractWallet.java @@ -17,11 +17,15 @@ public abstract class AbstractWallet extends AbstractNode{ public abstract void leave(); // The amount this wallet currently holds - public int amount; + protected int amount; // The name of this wallet (does never change, no // duplicates in network assumed) public final String name; + + public int getAmount(){ + return amount; + } } diff --git a/src/fucoin/Main.java b/src/fucoin/Main.java index 494bce4..b911900 100644 --- a/src/fucoin/Main.java +++ b/src/fucoin/Main.java @@ -10,6 +10,7 @@ import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; import fucoin.actions.join.ServerActionJoin; +import fucoin.actions.transaction.ActionInvokeSentMoney; import fucoin.supervisor.SuperVisor; @@ -22,7 +23,7 @@ public class Main { Config config = ConfigFactory.parseFile(file); ActorSystem system = ActorSystem.create("Core", config); ActorRef superVisorActor = system.actorOf(SuperVisor.props(),"SuperVisor"); - List<ActorRef> activeActors = new ArrayList<ActorRef>(); + List<ActorRef> activeActors = new ArrayList<>(); ActorRef a1 = system.actorOf(Wallet.props(null,"","Main",superVisorActor),"Main"); ActorRef a2 = system.actorOf(Wallet.props(a1,"Main","Main2",superVisorActor),"Main2"); superVisorActor.tell(new ServerActionJoin("Main"), a1); diff --git a/src/fucoin/Wallet.java b/src/fucoin/Wallet.java index 70f26fd..9aa7c79 100644 --- a/src/fucoin/Wallet.java +++ b/src/fucoin/Wallet.java @@ -13,161 +13,181 @@ import fucoin.actions.transaction.ActionInvokeSentMoney; import fucoin.gui.IWalletControle; import fucoin.gui.IWalletGuiControle; -public class Wallet extends AbstractWallet implements IWalletControle{ - - private ActorRef preknownNeighbour; - private ActorRef remoteSuperVisorActor; - private IWalletGuiControle gui; - private String preknownNeighbourName; - private boolean isActive; - - public Wallet(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) { - super(walletName); - this.preknownNeighbourName=preknownNeighbourName; - this.preknownNeighbour=preknownNeighbour; - this.remoteSuperVisorActor=remoteSuperVisorActor; - } - - public void addAmount(int amount) { - setAmount(this.amount+amount); - log(" My amount is now "+this.amount); - - } - - @Override - public void leave() { - getSelf().tell(new ActionInvokeLeave(), getSelf()); - } - - @Override - public void onReceive(Object message) { - log(message.getClass().getSimpleName()); - - //log(getSender().path().name()+" invokes "+getSelf().path().name()+" to do "+message.getClass().getSimpleName()); - if(message instanceof ActionInvokeRevive){ - ((ActionInvokeRevive) message).doAction(this); - } - if(!isActive&&!(message instanceof ActionInvokeRevive))return; - //System.out.println(message); - if(message instanceof ClientAction){ - ((ClientAction) message).doAction(this); - } - - } - - @Override - public void preStart() throws Exception { - isActive=true; - if(gui!=null){ - gui.setAddress(getAddress()); - } - String path = "akka.tcp://Core@127.0.0.1:1234/user/Main"; - //System.out.println(getContext().provider().getExternalAddressFor(getSelf().path().address())); - //log("my address should be "+getAddress()); - //log(""+preknownNeighbour); - //knownNeighbors.put(getName(),getSelf()); - - //System.out.println(knownNeighbors); - if(preknownNeighbour!=null){ - addKnownNeighbor(preknownNeighbourName,preknownNeighbour); - preknownNeighbour.tell(new ActionJoin(), getSelf()); - ActionJoinAnswer aja = new ActionJoinAnswer(); - aja.someNeighbors.putAll(getKnownNeighbors()); - aja.someNeighbors.put(name, getSelf()); - preknownNeighbour.tell(aja, getSelf()); - - } - //setAmount(100); - //remoteSuperVisorActor.tell(new ServerActionJoin(name), getSelf()); - } - - @Override - public void postStop() throws Exception { - leave(); - super.postStop(); - - } - - - public static Props props(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) { - return Props.create(Wallet.class,new WalletCreator(preknownNeighbour,preknownNeighbourName,walletName,remoteSuperVisorActor)); - } - - @Override - public boolean equals(Object obj) { - if(obj instanceof Wallet){ - Wallet wobj = (Wallet) obj; - return amount==wobj.amount&&name.equals(wobj.name); - } - return false; - } - - public void setGui(IWalletGuiControle gui) { - this.gui=gui; - } - - public void setAmount(int amount){ - this.amount = amount; - if(remoteSuperVisorActor != null){ - remoteSuperVisorActor.tell(new ActionGetAmountAnswer(getAddress(), getName(), amount), getSelf()); - } - if(gui!=null){ - gui.setAmount(this.amount); - } - } - - public ActorRef getPreknownNeighbour() { - return preknownNeighbour; - } - - public ActorRef getRemoteSuperVisorActor() { - return remoteSuperVisorActor; - } - - public IWalletGuiControle getGui() { - return gui; - } - - public String getPreknownNeighbourName() { - return preknownNeighbourName; - } - - public boolean isActive() { - return isActive; - } - - @Override - public boolean addKnownNeighbor(String key, ActorRef value) { - log(key+" is newNeighbor?"+!getKnownNeighbors().containsKey(key)); - if(getKnownNeighbors().containsKey(key)||key.equals(name)){ - return false; - } - boolean newNeighbor = super.addKnownNeighbor(key, value); - if(gui!=null&&newNeighbor){ - gui.addKnownAddress(key); - } - return newNeighbor; - } - - public void setPreknownNeighbour(ActorRef preknownNeighbour) { - this.preknownNeighbour = preknownNeighbour; - } - - public void setRemoteSuperVisorActor(ActorRef remoteSuperVisorActor) { - this.remoteSuperVisorActor = remoteSuperVisorActor; - } - - public void setPreknownNeighbourName(String preknownNeighbourName) { - this.preknownNeighbourName = preknownNeighbourName; - } - - public void setActive(boolean isActive) { - this.isActive = isActive; - } - - @Override - public void send(String address, int amount) { - getSelf().tell(new ActionInvokeSentMoney(address, amount), getSelf()); - } +public class Wallet extends AbstractWallet implements IWalletControle { + + private ActorRef preknownNeighbour; + private ActorRef remoteSuperVisorActor; + private IWalletGuiControle gui; + private String preknownNeighbourName; + private boolean isActive; + + public Wallet(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) { + super(walletName); + this.preknownNeighbourName = preknownNeighbourName; + this.preknownNeighbour = preknownNeighbour; + this.remoteSuperVisorActor = remoteSuperVisorActor; + } + + public void addAmount(int amount) { + setAmount(this.amount + amount); + log(" My amount is now " + this.amount); + } + + @Override + public void leave() { + getSelf().tell(new ActionInvokeLeave(), getSelf()); + } + + @Override + public void onReceive(Object message) { + + //log(getSender().path().name() + " invokes " + getSelf().path().name() + " to do " + message.getClass().getSimpleName()); + if (message instanceof ActionInvokeRevive) { + ((ActionInvokeRevive) message).doAction(this); + } + if (!isActive && !(message instanceof ActionInvokeRevive)) return; + //System.out.println(message); + if (message instanceof ClientAction) { + ((ClientAction) message).doAction(this); + } + + } + + @Override + public void preStart() throws Exception { + isActive = true; + if (gui != null) { + gui.setAddress(getAddress()); + } + String path = "akka.tcp://Core@127.0.0.1:1234/user/Main"; + //System.out.println(getContext().provider().getExternalAddressFor(getSelf().path().address())); + //log("my address should be "+getAddress()); + //log(""+preknownNeighbour); + //knownNeighbors.put(getName(),getSelf()); + + //System.out.println(knownNeighbors); + if (preknownNeighbour != null) { + addKnownNeighbor(preknownNeighbourName, preknownNeighbour); + preknownNeighbour.tell(new ActionJoin(), getSelf()); + ActionJoinAnswer aja = new ActionJoinAnswer(); + aja.someNeighbors.putAll(getKnownNeighbors()); + aja.someNeighbors.put(name, getSelf()); + preknownNeighbour.tell(aja, getSelf()); + + } + //setAmount(100); + //remoteSuperVisorActor.tell(new ServerActionJoin(name), getSelf()); + } + + @Override + public void postStop() throws Exception { + leave(); + super.postStop(); + + } + + + public static Props props(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) { + return Props.create(Wallet.class, new WalletCreator(preknownNeighbour, preknownNeighbourName, walletName, remoteSuperVisorActor)); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Wallet) { + Wallet wobj = (Wallet) obj; + return amount == wobj.amount && name.equals(wobj.name); + } + return false; + } + + public void setGui(IWalletGuiControle gui) { + this.gui = gui; + } + + public void setAmount(int amount) { + this.amount = amount; + if (remoteSuperVisorActor != null) { + remoteSuperVisorActor.tell(new ActionGetAmountAnswer(getAddress(), getName(), amount), getSelf()); + } + if (gui != null) { + gui.setAmount(this.amount); + } + } + + public int getAmount() { + return amount; + } + + public ActorRef getPreknownNeighbour() { + return preknownNeighbour; + } + + public ActorRef getRemoteSuperVisorActor() { + return remoteSuperVisorActor; + } + + public IWalletGuiControle getGui() { + return gui; + } + + public String getPreknownNeighbourName() { + return preknownNeighbourName; + } + + public boolean isActive() { + return isActive; + } + + @Override + public boolean addKnownNeighbor(String key, ActorRef value) { + System.out.println(key + " is newNeighbor of "+name+"?" + !getKnownNeighbors().containsKey(key)); + if (getKnownNeighbors().containsKey(key) || key.equals(name)) { + return false; + } + + boolean newNeighbor = super.addKnownNeighbor(key, value); + if (gui != null && newNeighbor) { + gui.addKnownAddress(key); + } + return newNeighbor; + } + + public void setPreknownNeighbour(ActorRef preknownNeighbour) { + this.preknownNeighbour = preknownNeighbour; + } + + public void setRemoteSuperVisorActor(ActorRef remoteSuperVisorActor) { + this.remoteSuperVisorActor = remoteSuperVisorActor; + } + + public void setPreknownNeighbourName(String preknownNeighbourName) { + this.preknownNeighbourName = preknownNeighbourName; + } + + @Override + public void log(String msg) { + if (gui != null) { + gui.addLogMsg(msg); + } else { + System.out.println(msg); + } + } + + public void logTransaction(String msg){ + if (gui != null) { + gui.addTransactionLogMessage(msg); + } else { + System.out.println(msg); + } + } + + public void setActive(boolean isActive) { + this.isActive = isActive; + } + + @Override + public void send(String address, int amount) { + getSelf().tell(new ActionInvokeSentMoney(address, amount), getSelf()); + } } diff --git a/src/fucoin/actions/join/ActionJoinAnswer.java b/src/fucoin/actions/join/ActionJoinAnswer.java index b230b1a..0750e85 100644 --- a/src/fucoin/actions/join/ActionJoinAnswer.java +++ b/src/fucoin/actions/join/ActionJoinAnswer.java @@ -15,7 +15,7 @@ public class ActionJoinAnswer extends ClientAction{ public final HashMap<String, ActorRef> someNeighbors = new HashMap<>(); protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, Wallet wallet) { - log("someNeighbors:"+someNeighbors); + log("Addressed to "+self.path().name()+" from "+sender.path().name()+": someNeighbors:"+someNeighbors); for(Entry<String, ActorRef> neighbor : someNeighbors.entrySet()){ wallet.addKnownNeighbor(neighbor.getKey(),neighbor.getValue()); } diff --git a/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java b/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java index 9336928..0635d72 100644 --- a/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java +++ b/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java @@ -14,7 +14,7 @@ public class ActionSearchMyWalletAnswer extends Persist { @Override protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, Wallet wallet) { - wallet.setAmount(w.amount); + wallet.setAmount(w.getAmount()); sender.tell(new ActionInvalidate(wallet.name), self); } } diff --git a/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java b/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java index 2b72a72..5236bf4 100644 --- a/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java +++ b/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java @@ -6,52 +6,59 @@ import fucoin.Wallet; import fucoin.actions.ClientAction; import fucoin.supervisor.DistributedCommitedTransferRequest; -public class ActionCommitDistributedCommitedTransfer extends ClientAction{ - - private ActorRef source; - private ActorRef target; - private int amount; - private boolean granted; - private long timestamp; - private long id; - - - public ActionCommitDistributedCommitedTransfer(ActorRef source, - ActorRef target, int amount, boolean granted, long timestamp, long id) { - this.source=source; - this.target=target; - this.amount=amount; - this.granted=granted; - this.timestamp=timestamp; - this.id=id; - } - - public ActionCommitDistributedCommitedTransfer( - DistributedCommitedTransferRequest outdatedRequest) { - this.source=outdatedRequest.getSource(); - this.target=outdatedRequest.getTarget(); - this.amount=0; - this.granted=false; - this.timestamp=outdatedRequest.getTimeout(); - this.id=outdatedRequest.getId(); - } - - @Override - protected void onAction(ActorRef sender, ActorRef self, - UntypedActorContext context, Wallet wallet) { - log("ActionCommitDistributedCommitedTransfer is granted?"+granted); - if(granted){ - Integer sourceAmount = wallet.amounts.getOrDefault(source,0); - Integer targetAmount = wallet.amounts.getOrDefault(target,0); - wallet.amounts.put(source,sourceAmount-amount); - wallet.amounts.put(target,targetAmount+amount); - if(source.compareTo(self)==0)wallet.amount-=amount; - else if(target.compareTo(self)==0)wallet.amount+=amount; - wallet.log("have now "+wallet.amounts.get(self)+" Fucoins"); - }else{ - log("abort transaction with id"+id); - } - log("wallet.amounts:"+wallet.amounts); - } +public class ActionCommitDistributedCommitedTransfer extends ClientAction { + + private ActorRef source; + private ActorRef target; + protected int amount; + private boolean granted; + private long timestamp; + private long id; + + + public ActionCommitDistributedCommitedTransfer(ActorRef source, + ActorRef target, int amount, boolean granted, long timestamp, long id) { + this.source = source; + this.target = target; + this.amount = amount; + this.granted = granted; + this.timestamp = timestamp; + this.id = id; + } + + public ActionCommitDistributedCommitedTransfer( + DistributedCommitedTransferRequest outdatedRequest) { + this.source = outdatedRequest.getSource(); + this.target = outdatedRequest.getTarget(); + this.amount = 0; + this.granted = false; + this.timestamp = outdatedRequest.getTimeout(); + this.id = outdatedRequest.getId(); + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + System.out.println(self.path().name() + ": ActionCommitDistributedCommitedTransfer is granted?" + granted); + if (granted) { + + Integer sourceAmount = wallet.amounts.getOrDefault(source, 0); + Integer targetAmount = wallet.amounts.getOrDefault(target, 0); + wallet.amounts.put(source, sourceAmount - amount); + wallet.amounts.put(target, targetAmount + amount); + + if (source.compareTo(self) == 0) { + wallet.setAmount(wallet.getAmount() - amount); + wallet.logTransaction("Sent " + amount + " FUC to " + target.path().name()); + } else if (target.compareTo(self) == 0) { + wallet.setAmount(wallet.getAmount() + amount); + wallet.logTransaction("Received " + amount + " FUC from " + source.path().name()); + } + + } else { + log("abort transaction with id" + id); + } + log("wallet.amounts:" + wallet.amounts); + } } diff --git a/src/fucoin/actions/transaction/ActionGetAmount.java b/src/fucoin/actions/transaction/ActionGetAmount.java index ad9737b..f14f8ae 100644 --- a/src/fucoin/actions/transaction/ActionGetAmount.java +++ b/src/fucoin/actions/transaction/ActionGetAmount.java @@ -9,7 +9,7 @@ public class ActionGetAmount extends Transaction { @Override protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, Wallet wallet) { - ActionGetAmountAnswer agaa = new ActionGetAmountAnswer(wallet.getAddress(),wallet.getName(),wallet.amount); + ActionGetAmountAnswer agaa = new ActionGetAmountAnswer(wallet.getAddress(),wallet.getName(),wallet.getAmount()); sender.tell(agaa, self); } diff --git a/src/fucoin/actions/transaction/ActionInvokeSentMoney2.java b/src/fucoin/actions/transaction/ActionInvokeSentMoney2.java deleted file mode 100644 index 743e0b8..0000000 --- a/src/fucoin/actions/transaction/ActionInvokeSentMoney2.java +++ /dev/null @@ -1,22 +0,0 @@ -package fucoin.actions.transaction; - -import akka.actor.ActorRef; -import akka.actor.UntypedActorContext; -import fucoin.Wallet; - -public class ActionInvokeSentMoney2 extends Transaction{ - public final String name; - public final int amount; - public ActionInvokeSentMoney2(String name, int amount) { - this.name=name; - this.amount = amount; - } - @Override - protected void onAction(ActorRef sender, ActorRef self, - UntypedActorContext context, Wallet wallet) { - if(wallet.getKnownNeighbors().containsKey(name)){ - wallet.addAmount(-amount); - wallet.getKnownNeighbors().get(name).tell(new ActionReceiveTransaction(amount), self); - } - } -} diff --git a/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java b/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java index decf2b9..26eb49e 100644 --- a/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java +++ b/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java @@ -4,30 +4,31 @@ import akka.actor.ActorRef; import akka.actor.UntypedActorContext; import fucoin.Wallet; -public class ActionPrepareDistributedCommitedTransfer extends Transaction{ +public class ActionPrepareDistributedCommitedTransfer extends Transaction { - private ActorRef source; - private ActorRef target; - private int amount; - private long timestamp; - private long id; + private ActorRef source; + private ActorRef target; + private int amount; + private long timestamp; + private long id; - public ActionPrepareDistributedCommitedTransfer(ActorRef source, - ActorRef target, int amount, long timestamp, long id) { - this.source=source; - this.target=target; - this.amount=amount; - this.timestamp=timestamp; - this.id=id; - } + public ActionPrepareDistributedCommitedTransfer(ActorRef source, + ActorRef target, int amount, long timestamp, long id) { + this.source = source; + this.target = target; + this.amount = amount; + this.timestamp = timestamp; + this.id = id; + } - @Override - protected void onAction(ActorRef sender, ActorRef self, - UntypedActorContext context, Wallet wallet) { - boolean granted = sender.compareTo(source)==0 //sender is supervisor(bank) has allways money - ||(wallet.amounts.containsKey(source) //sender is unknown, might be valid - &&wallet.amounts.getOrDefault(source,0)>=amount) ; //sender have enough money - sender.tell(new ActionPrepareDistributedCommitedTransferAnswer(source, target, amount,timestamp,granted,id),self); - } + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + boolean granted = amount > 0 && + (sender.compareTo(source) == 0 //sender is supervisor(bank) has always money + || (wallet.amounts.containsKey(source) //sender is unknown, might be valid + && wallet.amounts.getOrDefault(source, 0) >= amount)); //sender have enough money + sender.tell(new ActionPrepareDistributedCommitedTransferAnswer(source, target, amount, timestamp, granted, id), self); + } } diff --git a/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java b/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java index e479c38..8a01b2e 100644 --- a/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java +++ b/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java @@ -34,6 +34,7 @@ public class ActionPrepareDistributedCommitedTransferAnswer extends CoordinatorT if(request==null)//unknown DistributedCommitedTransferRequest ignore return; int newCount = request.addPositiveAnswer(sender); + System.out.println(newCount+" have agreed on request"+id); if(newCount == superVisor.getKnownNeighbors().size()){ ActionCommitDistributedCommitedTransfer acdct = new ActionCommitDistributedCommitedTransfer(source,target,amount,true,timestamp,id); for(ActorRef neighbor : request.getAnswers()){ diff --git a/src/fucoin/actions/transaction/ActionReceiveTransaction.java b/src/fucoin/actions/transaction/ActionReceiveTransaction.java index 6abdc2a..da9aa55 100644 --- a/src/fucoin/actions/transaction/ActionReceiveTransaction.java +++ b/src/fucoin/actions/transaction/ActionReceiveTransaction.java @@ -13,6 +13,6 @@ public class ActionReceiveTransaction extends Transaction { @Override protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, Wallet wallet) { - wallet.addAmount(wallet.amount); + wallet.addAmount(wallet.getAmount()); } } diff --git a/src/fucoin/gui/IWalletGuiControle.java b/src/fucoin/gui/IWalletGuiControle.java index 55d46ac..dcfa621 100644 --- a/src/fucoin/gui/IWalletGuiControle.java +++ b/src/fucoin/gui/IWalletGuiControle.java @@ -6,6 +6,7 @@ public interface IWalletGuiControle { public void setAmount(int amount); public void addKnownAddress(String address); public void addLogMsg(String msg); + public void addTransactionLogMessage(String message); diff --git a/src/fucoin/gui/LogMessage.java b/src/fucoin/gui/LogMessage.java new file mode 100644 index 0000000..c2928d0 --- /dev/null +++ b/src/fucoin/gui/LogMessage.java @@ -0,0 +1,26 @@ +package fucoin.gui; + + +public class LogMessage { + + private String message; + private boolean transactionRelated; + + public LogMessage(String message, boolean transactionRelated){ + this.message = message; + this.transactionRelated = transactionRelated; + } + + public String getMessage() { + return message; + } + + public boolean isTransactionRelated() { + return transactionRelated; + } + + @Override + public String toString(){ + return getMessage(); + } +} diff --git a/src/fucoin/gui/WalletGui.java b/src/fucoin/gui/WalletGui.java index 0c09c87..564eaea 100644 --- a/src/fucoin/gui/WalletGui.java +++ b/src/fucoin/gui/WalletGui.java @@ -1,163 +1,202 @@ package fucoin.gui; -import java.awt.BorderLayout; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; - -import javax.swing.DefaultListModel; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JTextField; - - -public class WalletGui implements IWalletGuiControle{ - DefaultListModel<String> log = new DefaultListModel<String>(); - - private JFrame window = new JFrame("test"); - JPanel topPanel = new JPanel(); - JLabel lblMyAddress = new JLabel("My Address:"); - JTextField txtMyAddress = new JTextField("<MyAddress>"); - JLabel lblEmpty = new JLabel(""); - JLabel lblMyAmount = new JLabel("My FUCs"); - JTextField txtMyAmount = new JTextField("<MyFUCs>"); - JPanel centerPanel = new JPanel(); - JLabel lblSendTo = new JLabel("Send to:"); - JComboBox<String> txtSendTo = new JComboBox<String>(); - JLabel lblSendAmount = new JLabel("Amount:"); - JTextField txtSendAmount = new JTextField("<Amount>"); - JButton btnSend = new JButton("Send"); - JButton btnSearch = new JButton("Search"); - JButton btnStore = new JButton("Store"); - JButton btnExit = new JButton("Exit"); - JPanel bottomPanel = new JPanel(); - JList<String> txtLog = new JList<String>(log); - -public WalletGui(IWalletControle walletControle) { - - - window.setSize(400, 600); - window.setLayout(new GridLayout(3, 1)); - topPanel.setLayout(new GridLayout(2, 3)); - // Row 1 - topPanel.add(lblMyAddress); - topPanel.add(txtMyAddress); - topPanel.add(lblEmpty); - // Row 2 - topPanel.add(lblMyAmount); - topPanel.add(txtMyAmount); - window.add(topPanel); - //<hr> - centerPanel.setLayout(new GridLayout(4, 1)); - // Row 1 - JPanel centerup = new JPanel(); - centerup.setLayout(new BorderLayout()); - centerup.add(lblSendTo,BorderLayout.WEST); - centerup.add(txtSendTo,BorderLayout.CENTER); - centerPanel.add(centerup); - - JPanel centerup2 = new JPanel(); - centerup2.setLayout(new BorderLayout()); - JTextField sendToNewEdt = new JTextField(); - centerup2.add(sendToNewEdt,BorderLayout.CENTER); - JButton addNewButton = new JButton("Add"); - addNewButton.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - txtSendTo.addItem(sendToNewEdt.getText()); - } - }); - centerup2.add(addNewButton,BorderLayout.EAST); - centerPanel.add(centerup2); - - // Row 2 - JPanel centerdown = new JPanel(); - centerdown.setLayout(new GridLayout(1, 3)); - centerdown.add(lblSendAmount); - centerdown.add(txtSendAmount); - centerdown.add(btnSend); - centerPanel.add(centerdown); - //centerPanel.add(new JLabel("")); - // Row 3 - JPanel centerdown2 = new JPanel(); - centerdown2.setLayout(new GridLayout(1, 3)); - centerdown2.add(btnSearch); - centerdown2.add(btnStore); - centerdown2.add(btnExit); - centerPanel.add(centerdown2); - window.add(centerPanel); - //<hr> - bottomPanel.setLayout(new GridLayout(1, 1)); - bottomPanel.add(txtLog); - window.add(bottomPanel); - window.setVisible(true); - - btnSend.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - walletControle.send(txtSendTo.getSelectedItem().toString(), Integer.parseInt(txtSendAmount.getText())); - } - }); - - btnStore.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - - } - }); - - btnExit.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent e) { - window.dispose(); - } - }); - - window.addWindowListener(new WindowAdapter() { - - @Override - public void windowClosing(WindowEvent e) { - System.out.println("window closing"); - walletControle.leave(); - super.windowClosing(e); - - } - @Override - public void windowClosed(WindowEvent e) { - System.out.println("window closing"); - walletControle.leave(); - super.windowClosing(e); - } - }); -} +import com.sun.tools.javac.comp.Flow; -@Override -public void setAddress(String address) { - txtMyAddress.setText(address); - window.setTitle(address); -} -@Override -public void setAmount(int amount) { - txtMyAmount.setText(""+amount); -} +import java.awt.*; +import java.awt.event.*; +import java.util.Enumeration; -@Override -public void addKnownAddress(String address) { - - txtSendTo.addItem(address); -} -@Override -public void addLogMsg(String msg) { - log.addElement(msg); -} +import javax.swing.*; + +public class WalletGui implements IWalletGuiControle { + + private DefaultListModel<LogMessage> log = new DefaultListModel<>(); + + private JFrame window = new JFrame("test"); + private JPanel topPanel = new JPanel(); + private JLabel lblMyAddress = new JLabel("My Address:"); + private JTextField txtMyAddress = new JTextField("<MyAddress>"); + private JLabel lblEmpty = new JLabel(""); + private JLabel lblMyAmount = new JLabel("My FUCs"); + private JTextField txtMyAmount = new JTextField("<MyFUCs>"); + private JPanel centerPanel = new JPanel(); + private JLabel lblSendTo = new JLabel("Send to:"); + private JComboBox<String> txtSendTo = new JComboBox<>(); + private JLabel lblSendAmount = new JLabel("Amount:"); + private JTextField txtSendAmount = new JTextField(""); + private JButton btnSend = new JButton("Send"); + private JButton btnSearch = new JButton("Search"); + private JButton btnStore = new JButton("Store"); + private JButton btnExit = new JButton("Exit"); + private JPanel bottomPanel = new JPanel(); + private JList<LogMessage> txtLog = new JList<>(log); + private JScrollPane logPane = new JScrollPane(txtLog); + private JCheckBox showDebug; + + public WalletGui(IWalletControle walletControle) { + + window.setSize(400, 600); + window.setLayout(new GridLayout(3, 1)); + topPanel.setLayout(new GridLayout(2, 3)); + // Row 1 + topPanel.add(lblMyAddress); + topPanel.add(txtMyAddress); + topPanel.add(lblEmpty); + // Row 2 + topPanel.add(lblMyAmount); + topPanel.add(txtMyAmount); + window.add(topPanel); + //<hr> + centerPanel.setLayout(new GridLayout(4, 1)); + // Row 1 + JPanel centerup = new JPanel(); + centerup.setLayout(new BorderLayout()); + centerup.add(lblSendTo, BorderLayout.WEST); + centerup.add(txtSendTo, BorderLayout.CENTER); + centerPanel.add(centerup); + + JPanel centerup2 = new JPanel(); + centerup2.setLayout(new BorderLayout()); + JTextField sendToNewEdt = new JTextField(); + centerup2.add(sendToNewEdt, BorderLayout.CENTER); + JButton addNewButton = new JButton("Add"); + addNewButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + txtSendTo.addItem(sendToNewEdt.getText()); + } + }); + centerup2.add(addNewButton, BorderLayout.EAST); + centerPanel.add(centerup2); + + // Row 2 + JPanel centerdown = new JPanel(); + centerdown.setLayout(new GridLayout(1, 3)); + centerdown.add(lblSendAmount); + centerdown.add(txtSendAmount); + centerdown.add(btnSend); + centerPanel.add(centerdown); + //centerPanel.add(new JLabel("")); + // Row 3 + JPanel centerdown2 = new JPanel(); + centerdown2.setLayout(new GridLayout(1, 3)); + centerdown2.add(btnSearch); + centerdown2.add(btnStore); + centerdown2.add(btnExit); + centerPanel.add(centerdown2); + window.add(centerPanel); + //<hr> + bottomPanel.setLayout(new BorderLayout()); + + showDebug = new JCheckBox("Show debug messages in transaction log"); + showDebug.addItemListener(e -> { + if (e.getStateChange() == ItemEvent.SELECTED) { + txtLog.setModel(log); + } else { + updateFilteredLog(); + } + }); + + bottomPanel.add(showDebug, BorderLayout.NORTH); + bottomPanel.add(logPane, BorderLayout.CENTER); + + window.add(bottomPanel); + window.setVisible(true); + + btnSend.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + walletControle.send(txtSendTo.getSelectedItem().toString(), Integer.parseInt(txtSendAmount.getText())); + } + }); + + btnStore.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + + } + }); + + btnExit.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + window.dispose(); + } + }); + + window.addWindowListener(new WindowAdapter() { + + @Override + public void windowClosing(WindowEvent e) { + System.out.println("window closing"); + walletControle.leave(); + super.windowClosing(e); + + } + + @Override + public void windowClosed(WindowEvent e) { + System.out.println("window closing"); + walletControle.leave(); + super.windowClosing(e); + } + }); + } + + @Override + public void setAddress(String address) { + txtMyAddress.setText(address); + window.setTitle(address); + } + + @Override + public void setAmount(int amount) { + txtMyAmount.setText(String.valueOf(amount)); + } + + @Override + public void addKnownAddress(String address) { + txtSendTo.addItem(address); + } + + @Override + public void addLogMsg(String msg) { + log(new LogMessage(msg, false)); + } + + @Override + public void addTransactionLogMessage(String message) { + log(new LogMessage(message, true)); + } + + private void log(LogMessage logMessage) { + SwingUtilities.invokeLater(() -> { + log.addElement(logMessage); + + if (!showDebug.isSelected()) { + updateFilteredLog(); + } + + // auto scroll to the bottom + txtLog.ensureIndexIsVisible(log.size() - 1); + }); + } + + private void updateFilteredLog() { + + DefaultListModel<LogMessage> filteredLog = new DefaultListModel<>(); + Enumeration<LogMessage> elements = log.elements(); + while (elements.hasMoreElements()) { + LogMessage logMessage = elements.nextElement(); + if (logMessage.isTransactionRelated()) { + filteredLog.addElement(logMessage); + } + } + + txtLog.setModel(filteredLog); + } } diff --git a/src/fucoin/supervisor/AmountTableModel.java b/src/fucoin/supervisor/AmountTableModel.java index fb91ce4..a8a6a8a 100644 --- a/src/fucoin/supervisor/AmountTableModel.java +++ b/src/fucoin/supervisor/AmountTableModel.java @@ -1,15 +1,33 @@ package fucoin.supervisor; import javax.swing.table.DefaultTableModel; +import java.util.Vector; -public class AmountTableModel extends DefaultTableModel{ -public AmountTableModel() { - super(new Object[]{"Address","Name","Amount"},0); -} +public class AmountTableModel extends DefaultTableModel { -public void clear() { - while(getRowCount()>0){ - removeRow(0); - } -} + public AmountTableModel() { + super(new Object[]{"Address", "Name", "Amount"}, 0); + } + + public void clear() { + while (getRowCount() > 0) { + removeRow(0); + } + } + + public void updateTable(String address, String name, int amount) { + + Vector<Object> rows = this.getDataVector(); + for (int i = 0; i < rows.size(); i++) { + if (rows.get(i) instanceof Vector){ + Vector<Object> row = (Vector<Object>) rows.get(i); + if(row.get(0).equals(address)){ + setValueAt(amount, i, 2); + return; + } + } + } + + this.addRow(new Object[]{address, name, amount}); + } } diff --git a/src/fucoin/supervisor/SuperVisor.java b/src/fucoin/supervisor/SuperVisor.java index a6adcaa..807af32 100644 --- a/src/fucoin/supervisor/SuperVisor.java +++ b/src/fucoin/supervisor/SuperVisor.java @@ -14,83 +14,95 @@ import akka.actor.ActorRef; import akka.actor.Props; import fucoin.AbstractNode; import fucoin.actions.Action; +import fucoin.actions.ClientAction; import fucoin.actions.persist.ActionInvokeUpdate; +import fucoin.actions.transaction.ActionGetAmountAnswer; +import fucoin.actions.transaction.SuperVisorAction; public class SuperVisor extends AbstractNode { - - private AmountTableModel amountTableModel; - private Label averageamountLbl; - - public SuperVisor(AmountTableModel amountTableModel, Label averageamountLbl) { - this.amountTableModel = amountTableModel; - this.averageamountLbl = averageamountLbl; - } - - @Override - public void onReceive(Object msg) { - log(msg.getClass().getSimpleName()); - - ((Action) msg).doAction(this); - } - - Semaphore mutex = new Semaphore(1); - private Map<Long,DistributedCommitedTransferRequest> requestQueue; - - public static Props props() { - return Props.create(SuperVisor.class, new SuperVisorCreator()); - } - - public void updateValues() { - getSelf().tell(new ActionInvokeUpdate(), getSelf()); - } - - public void exit() { - getContext().stop(getSelf()); - } - - @Override - public void postStop() throws Exception { - super.postStop(); - } - - public void addDistributedCommitedTransferRequest( - DistributedCommitedTransferRequest request) { - requestQueue.put(request.getId(),request); - } - - @Override - public void preStart() throws Exception { - super.preStart(); - requestQueue = new HashMap<Long,DistributedCommitedTransferRequest>(); - self().tell(new ActionUpdateQueue(), self()); - } - /** - * filters the request for outdated and removes them - * @return deleted outdated request - */ - public List<DistributedCommitedTransferRequest> updateList(){ - List<Long> deletesIds = new ArrayList<Long>(); - List<DistributedCommitedTransferRequest> deletes = new ArrayList<DistributedCommitedTransferRequest>(); - for(Entry<Long, DistributedCommitedTransferRequest> outdatedRequest : requestQueue.entrySet()){ - if(outdatedRequest.getValue().getTimeout()<System.currentTimeMillis()){ - deletesIds.add(outdatedRequest.getKey()); - deletes.add(outdatedRequest.getValue()); - } - } - for(Long delete : deletesIds){ - requestQueue.remove(delete); - } - - return deletes; - } - - public DistributedCommitedTransferRequest getRequest(Long id) { - DistributedCommitedTransferRequest searchedrequest = requestQueue.get(id); - return searchedrequest ; - } - - public void deleteRequest(DistributedCommitedTransferRequest request) { - requestQueue.remove(request.getId()); - } + + private AmountTableModel amountTableModel; + private Label averageamountLbl; + + public SuperVisor(AmountTableModel amountTableModel, Label averageamountLbl) { + this.amountTableModel = amountTableModel; + this.averageamountLbl = averageamountLbl; + } + + @Override + public void onReceive(Object msg) { + + // dirty but necessary since ActionGetAmountAnswer is a + // ClientAction for some reason + if (msg instanceof ActionGetAmountAnswer) { + ActionGetAmountAnswer answer = (ActionGetAmountAnswer) msg; + amountTableModel.updateTable(answer.address, answer.name, answer.amount); + } else if (msg instanceof SuperVisorAction) { + ((Action) msg).doAction(this); + } + } + + Semaphore mutex = new Semaphore(1); + private Map<Long, DistributedCommitedTransferRequest> requestQueue; + + public static Props props() { + return Props.create(SuperVisor.class, new SuperVisorCreator()); + } + + public void updateValues() { + getSelf().tell(new ActionInvokeUpdate(), getSelf()); + } + + public void exit() { + getContext().stop(getSelf()); + } + + @Override + public void postStop() throws Exception { + super.postStop(); + } + + public void addDistributedCommitedTransferRequest( + DistributedCommitedTransferRequest request) { + System.out.println("Füge Request in queue ein: " + request.getId()); + requestQueue.put(request.getId(), request); + } + + @Override + public void preStart() throws Exception { + super.preStart(); + requestQueue = new HashMap<>(); + self().tell(new ActionUpdateQueue(), self()); + } + + /** + * filters the request for outdated and removes them + * + * @return deleted outdated request + */ + public List<DistributedCommitedTransferRequest> updateList() { + List<Long> deletesIds = new ArrayList<Long>(); + List<DistributedCommitedTransferRequest> deletes = new ArrayList<DistributedCommitedTransferRequest>(); + for (Entry<Long, DistributedCommitedTransferRequest> outdatedRequest : requestQueue.entrySet()) { + if (outdatedRequest.getValue().getTimeout() < System.currentTimeMillis()) { + deletesIds.add(outdatedRequest.getKey()); + deletes.add(outdatedRequest.getValue()); + } + } + for (Long delete : deletesIds) { + requestQueue.remove(delete); + } + + return deletes; + } + + public DistributedCommitedTransferRequest getRequest(Long id) { + DistributedCommitedTransferRequest searchedrequest = requestQueue.get(id); + return searchedrequest; + } + + public void deleteRequest(DistributedCommitedTransferRequest request) { + requestQueue.remove(request.getId()); + } } -- GitLab