diff --git a/.gitignore b/.gitignore index 576fc86..31048f8 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,4 @@ Thumbs.db # jME (binaries) *.so +/bin/ diff --git a/BankClient/serverips.txt b/BankClient/serverips.txt new file mode 100644 index 0000000..e166652 --- /dev/null +++ b/BankClient/serverips.txt @@ -0,0 +1 @@ +10.0.10.108:6788 \ No newline at end of file diff --git a/BankClient/src/es/upm/dit/cnvr/client/ClientApp.java b/BankClient/src/es/upm/dit/cnvr/client/ClientApp.java index 65eea9f..b5f48c7 100644 --- a/BankClient/src/es/upm/dit/cnvr/client/ClientApp.java +++ b/BankClient/src/es/upm/dit/cnvr/client/ClientApp.java @@ -9,7 +9,7 @@ public class ClientApp { //Set true or false debug - public static boolean debug = true; + public static boolean debug = false; public ClientApp() { } @@ -18,7 +18,16 @@ public ClientApp() { public static void main(String[] args) { //throws Exception{ System.out.println("|****************************************************|"); System.out.println("|Welcome to the administration system of Eclipse Bank|"); - System.out.println("|****************************************************|"); + System.out.println("|*************************************************///|"); + System.out.println("| |||||||| |||||||| ////|"); + System.out.println("| || || ||| /////|"); + System.out.println("| || || ||| //////|"); + System.out.println("| |||||||| |||||||| ///////|"); + System.out.println("| || || ||| ////////|"); + System.out.println("| || || ||| /////////|"); + System.out.println("| |||||||| |||||||| //////////|"); + System.out.println("|////////////////////////////////////////////////////|"); + showOptions(); } @@ -30,19 +39,21 @@ public BankClient getAccount(int accountId){ public static void showOptions(){ System.out.println("| These are the operations you can do: |"); System.out.println("|1. Create a client |"); - System.out.println("| - Usage: CREATE [ClientName] [Balance] |"); + System.out.println("| - Usage: CREATE [Name and lastnames] [Balance] |"); System.out.println("|2. Read a client account |"); System.out.println("| - Usage: READ [Account ID] |"); System.out.println("|3. Update balance of a client account |"); System.out.println("| - Usage: UPDATE [Account ID] [New Balance] |"); System.out.println("|4. Delete a client account |"); //ClientName for security purposes - System.out.println("| - Usage: DELETE [Account ID] [ClientName] |"); - System.out.println("|5. Show these options again |"); + System.out.println("| - Usage: DELETE [Account ID] [Name and lastnames]|"); + System.out.println("|5. Show all accounts |"); + System.out.println("| - Usage: SHOW |"); + System.out.println("|6. Show these options again |"); System.out.println("| - Usage: OPTIONS |"); + System.out.println("|----------------------------------------------------|"); + System.out.println("|Enter an operation |"); while (true){ - System.out.println("|----------------------------------------------------|"); - System.out.println("|Enter an operation |"); Scanner keyboard = new Scanner(System.in); String input = keyboard.nextLine(); String[] input_parts = input.split(" "); @@ -52,39 +63,55 @@ public static void showOptions(){ String accountId = "0"; String clientName = ""; Double balance = 0.0; - switch (input_parts[0]) { + switch (input_parts[0].toUpperCase()) { case "CREATE": - //Check options - if(input_parts[1] == null || input_parts[2] == null || input_parts.length > 3){ - System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); - break; - } - //Variables for method + try { + //Check options + if (input_parts[1] == null || input_parts[2] == null || input_parts[3] == null + || input_parts[4] == null || input_parts.length > 5) { + System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); + break; + } + } catch (Exception e) { + System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); + break; + } + //Variables for method op = OperationEnum.CREATE_CLIENT; - clientName = input_parts[1]; - balance = Double.parseDouble(input_parts[2]); + clientName = input_parts[1]+" "+input_parts[2]+" "+input_parts[3]; + balance = Double.parseDouble(input_parts[4]); //Send result = operateAndSend(op,accountId,clientName,balance); break; case "READ": - //Check options - if(input_parts[1] == null || input_parts.length > 2){ - System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); - break; - } - //Variables for method + try { + //Check options + if (input_parts[1] == null || input_parts.length > 2) { + System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); + break; + } + } catch (Exception e) { + System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); + break; + } + //Variables for method op = OperationEnum.READ_CLIENT; accountId = input_parts[1]; //Send result = operateAndSend(op,accountId,clientName,balance); break; case "UPDATE": - //Check options - if(input_parts[1] == null || input_parts[2] == null || input_parts.length > 3){ - System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); - break; - } - //Variables for method + try { + //Check options + if (input_parts[1] == null || input_parts[2] == null || input_parts.length > 3) { + System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); + break; + } + } catch (Exception e) { + System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); + break; + } + //Variables for method op = OperationEnum.UPDATE_CLIENT; accountId = input_parts[1]; balance = Double.parseDouble(input_parts[2]); @@ -92,18 +119,40 @@ public static void showOptions(){ result = operateAndSend(op,accountId,clientName,balance); break; case "DELETE": - //Check options - if(input_parts[1] == null || input_parts[2] == null || input_parts.length > 3){ - System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); - break; - } - //Variables for method + try { + //Check options + if (input_parts[1] == null || input_parts[2] == null || input_parts[3] == null + || input_parts[4] == null || input_parts.length > 5) { + System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); + break; + } + } catch (Exception e) { + System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); + break; + } + //Variables for method op = OperationEnum.DELETE_CLIENT; accountId = input_parts[1]; - clientName = input_parts[2]; + clientName = input_parts[2]+" "+input_parts[3]+" "+input_parts[4]; //Send result = operateAndSend(op,accountId,clientName,balance); break; + case "SHOW": + try { + //Check options + if (input_parts.length > 1) { + System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); + break; + } + } catch (Exception e) { + System.out.println("¡¡¡¡You are not using this operation properly!!!!\n\n"); + break; + } + //Variables for method + op = OperationEnum.SHOW_ALL; + //Send + result = operateAndSend(op,accountId,clientName,balance); + break; case "OPTIONS": showOptions(); break; @@ -116,11 +165,7 @@ public static void showOptions(){ } catch (InterruptedException e) { e.printStackTrace(); } - if(result){ - System.out.println(">>Successful operation"); - } else{ - System.out.println(">>Unsuccessful operation"); - } + } } @@ -132,7 +177,6 @@ public static boolean operateAndSend(OperationEnum operation, String accountId,S System.out.println("Account ID: " + accountId); System.out.println("Client Name: " + clientName); System.out.println("Balance: " + quantity); - } BankClient bc = new BankClient(accountId, clientName, quantity); Transaction transaction = new Transaction(operation,bc); diff --git a/BankClient/src/es/upm/dit/cnvr/client/Receiver.java b/BankClient/src/es/upm/dit/cnvr/client/Receiver.java index 609f939..3055669 100644 --- a/BankClient/src/es/upm/dit/cnvr/client/Receiver.java +++ b/BankClient/src/es/upm/dit/cnvr/client/Receiver.java @@ -37,13 +37,12 @@ public void run() { try { // 1. Create the Stream for the input inFromServer =new ObjectInputStream(clientSocket.getInputStream()); - String message; // 2. Read from the connection transaction = (Transaction) inFromServer.readObject(); BankClient bc = transaction.getBankClient(); ServiceStatus status = transaction.getStatus(); System.out.println("<< Connection: Account recieved."); - System.out.println("<< The status of the operation is: " + status); + //System.out.println("<< The status of the operation is: " + status); if (bc == null) break; switch (transaction.getOperation().toString()) { @@ -65,12 +64,33 @@ public void run() { if(status == ServiceStatus.OK) System.out.println("<< Deleted client: " + transaction.getBankClient().getClientName()); break; + + case "SHOW_ALL": + if(status == ServiceStatus.OK){ + java.util.HashMap db = transaction.getClientdb().getClientDB(); + System.out.println("******************************************"); + for (java.util.HashMap.Entry entry : db.entrySet()) { + System.out.print("Account ID: " + entry.getValue().getAccount()); + System.out.print(" | Client Name: " + entry.getValue().getClientName()); + System.out.println(" | Balance: " + entry.getValue().getBalance()); + } + System.out.println("******************************************"); + } + break; default: System.out.println("<< There is an error state, consult with the admin"); } - System.out.println("<< ID: " + transaction.getBankClient().getAccount()); + System.out.println("Operation done in server: " + transaction.getHostname()); + System.out.println("<< ID: " + transaction.getBankClient().getAccount()); System.out.println("<< Balance " + transaction.getBankClient().getBalance()); + if(status==ServiceStatus.OK){ + System.out.println(">>Successful operation"); + } else{ + System.out.println(">>Unsuccessful operation. Contact the administrator"); + } + System.out.println("|----------------------------------------------------|"); + System.out.println("|Enter an operation |"); nReceiver ++; } catch (Exception e) { break; diff --git a/BankClient/src/es/upm/dit/cnvr/client/TCPClient.java b/BankClient/src/es/upm/dit/cnvr/client/TCPClient.java index 63e40de..d70f713 100644 --- a/BankClient/src/es/upm/dit/cnvr/client/TCPClient.java +++ b/BankClient/src/es/upm/dit/cnvr/client/TCPClient.java @@ -3,6 +3,9 @@ import java.io.*; import java.net.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Random; import es.upm.dit.cnvr.model.BankClient; @@ -19,9 +22,14 @@ public static void connection(Transaction transaction) { //throws Exception{ Socket clientSocket; ObjectOutputStream outToServer; int nTimes = 4; - String hostname = "127.0.0.1"; - int port = 6789; + ArrayList hostnamelist = getIps(); Random random = new java.util.Random(); + String server = hostnamelist.get(random.nextInt(hostnamelist.size())); + String hostname = server.split(":")[0]; + int port = Integer.parseInt(server.split(":")[1]); + System.out.println("hostname:" +hostname + "; port: "+port); + + int bound = 10; try { @@ -39,14 +47,6 @@ public static void connection(Transaction transaction) { //throws Exception{ receiver.start(); try { - if(ClientApp.debug){ - System.out.println("Debug operation"); - System.out.println("Transaction: the information fo the account to send is "); - System.out.println("Operation: " + operation); - System.out.println("Account ID: " + bc.getAccount()); - System.out.println("Client Name: " + bc.getClientName()); - System.out.println("Balance: " + bc.getBalance()); - } // 4. Write information to the connection outToServer.writeObject(transaction); outToServer.flush(); @@ -60,6 +60,17 @@ public static void connection(Transaction transaction) { //throws Exception{ receiver.finish(true, false, nTimes); } + private static ArrayList getIps(){ + ArrayList ips = new ArrayList(); + try { + Files.lines(Paths.get("serverips.txt")).forEach(ips::add); + } catch (IOException e) { + ips.add("127.0.0.1"); + System.out.println("Ips not found. Default: 127.0.0.1"); + e.printStackTrace(); + } + return ips; + } } diff --git a/BankClient/src/es/upm/dit/cnvr/model/ClientDB.java b/BankClient/src/es/upm/dit/cnvr/model/ClientDB.java index dea4e59..3e5bc57 100644 --- a/BankClient/src/es/upm/dit/cnvr/model/ClientDB.java +++ b/BankClient/src/es/upm/dit/cnvr/model/ClientDB.java @@ -34,36 +34,31 @@ public HashMap getClientDB() { public ServiceStatus createClient(BankClient client) { ServiceStatus stat = ServiceStatus.INFORMATION_MISSED; - if (clientDB.containsKey(client.getAccount())) { + if (clientDB.containsKey(client.getAccount()) && client.getBalance() >= 0) { // It already exists: We inform about it stat = ServiceStatus.EXISTING_CLIENT; }else { // It doesn't exists: We create it clientDB.put(client.getAccount(), client); - if(es.upm.dit.cnvr.client.ClientApp.debug){ - System.out.println("DB has: "); - System.out.println(clientDB.toString()); - } stat = ServiceStatus.OK; } + //System.out.println("DB: " + clientDB.toString()); + printDb(); return stat; } - public BankClient readAccount(String clientAccount) { BankClient client = null; if (clientDB.containsKey(clientAccount)) client = clientDB.get(clientAccount); - if(es.upm.dit.cnvr.client.ClientApp.debug){ - System.out.println("DB has: "); - System.out.println(clientDB.toString()); - } + //System.out.println("DB: " + clientDB.toString()); + printDb(); return client; } public ServiceStatus update (String accountId, double balance) { ServiceStatus stat = ServiceStatus.INFORMATION_MISSED; - if (balance > 0 && clientDB.containsKey(accountId)){ + if (balance >= 0 && clientDB.containsKey(accountId)){ BankClient client = clientDB.get(accountId); client.setBalance(balance); clientDB.put(client.getAccount(), client); @@ -71,10 +66,8 @@ public ServiceStatus update (String accountId, double balance) { } else { stat = ServiceStatus.INFORMATION_INVALID; } - if(es.upm.dit.cnvr.client.ClientApp.debug){ - System.out.println("DB has: "); - System.out.println(clientDB.toString()); - } + //System.out.println("DB: " + clientDB.toString()); + printDb(); return stat; } @@ -86,14 +79,11 @@ public ServiceStatus deleteClient(String accountId, String clientName) { } else { stat = ServiceStatus.INFORMATION_INVALID; } - if(es.upm.dit.cnvr.client.ClientApp.debug){ - System.out.println("DB has: "); - System.out.println(clientDB.toString()); - } + //System.out.println("DB: " + clientDB.toString()); + printDb(); return stat; } - // XXX: Diria de cambiar esto por un getBank, porque es lo que realmente hace. No se si seria de utilidad aun asi public boolean createBank(ClientDB clientDB) { this.clientDB = clientDB.getClientDB(); return true; @@ -106,6 +96,17 @@ public String toString() { } return aux; } + + public void printDb(){ + java.util.HashMap db = clientDB; + System.out.println("******************************************"); + for (java.util.HashMap.Entry entry : db.entrySet()) { + System.out.print("Account ID: " + entry.getValue().getAccount()); + System.out.print(" | Client Name: " + entry.getValue().getClientName()); + System.out.println(" | Balance: " + entry.getValue().getBalance()); + } + System.out.println("******************************************"); + } } diff --git a/BankClient/src/es/upm/dit/cnvr/model/OperationEnum.java b/BankClient/src/es/upm/dit/cnvr/model/OperationEnum.java index f45a436..3c2c3a9 100644 --- a/BankClient/src/es/upm/dit/cnvr/model/OperationEnum.java +++ b/BankClient/src/es/upm/dit/cnvr/model/OperationEnum.java @@ -4,5 +4,6 @@ public enum OperationEnum { CREATE_CLIENT, READ_CLIENT, UPDATE_CLIENT, -DELETE_CLIENT +DELETE_CLIENT, +SHOW_ALL } diff --git a/BankClient/src/es/upm/dit/cnvr/model/Transaction.java b/BankClient/src/es/upm/dit/cnvr/model/Transaction.java index f532393..9059bcc 100644 --- a/BankClient/src/es/upm/dit/cnvr/model/Transaction.java +++ b/BankClient/src/es/upm/dit/cnvr/model/Transaction.java @@ -1,11 +1,22 @@ package es.upm.dit.cnvr.model; import java.io.Serializable; +import java.net.InetAddress; public class Transaction implements Serializable { private OperationEnum operation; private BankClient bankClient; private ServiceStatus status; + private ClientDB clientdb; + private String hostname; + + public ClientDB getClientdb() { + return clientdb; + } + + public void setClientdb(ClientDB clientdb) { + this.clientdb = clientdb; + } public Transaction(OperationEnum op, BankClient bc) { this.operation = op; @@ -27,6 +38,14 @@ public BankClient getBankClient() { public void setBankClient(BankClient bankClient) { this.bankClient = bankClient; } + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } @Override public String toString() { diff --git a/BankClient/src/es/upm/dit/cnvr/server/Barrier.java b/BankClient/src/es/upm/dit/cnvr/server/Barrier.java index 8d361cc..7481504 100644 --- a/BankClient/src/es/upm/dit/cnvr/server/Barrier.java +++ b/BankClient/src/es/upm/dit/cnvr/server/Barrier.java @@ -50,6 +50,7 @@ public Barrier(ZooKeeper zk, String root, int size, Integer mutexBarrier) { zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } + } catch (KeeperException e) { System.out .println("Keeper exception when instantiating queue: " @@ -97,17 +98,12 @@ boolean enter() throws KeeperException, InterruptedException{ System.out.println("He creado el nodoB: " + nodoB); while (true) { List list = zk.getChildren(root, true); - System.out.println(size); - System.out.println(list.size()); - - if (list.size() < size) { + if (list.size() < size && zk.exists("/boperationleave", false)== null) { synchronized (mutexBarrier) { - System.out.println("While antes del wait"); - System.out.println("He hecho wait con el mutexBarrier: " + System.identityHashCode(mutexBarrier)); - mutexBarrier.wait(); - System.out.println("While tras el wait"); + mutexBarrier.wait(1000); } } else { + System.out.println("Enter"); return true; } } @@ -123,16 +119,33 @@ boolean enter() throws KeeperException, InterruptedException{ boolean leave() throws KeeperException, InterruptedException{ System.out.println("Start leave barrier"); - Thread.sleep(1000); zk.delete(nodoB, 0); - System.out.println("He borrado el nodoB: " + nodoB); while (true) { List list = zk.getChildren(root, true); + Stat stat = zk.exists("/boperationleave", false); if (list.size() > 0) { synchronized (mutexBarrier) { - mutexBarrier.wait(); + if(stat == null){ + try{ + zk.create("/boperationleave", new byte[0], + Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); + } catch (Exception e1){ + System.out.println("Node boperationleave already created"); + + } + } + mutexBarrier.wait(1000); } } else { + System.out.println("Leave"); + if(stat != null){ + try{ + zk.delete("/boperationleave",0); + } catch (Exception e1){ + System.out.println("Node boperationleave already created"); + + } + } return true; } } diff --git a/BankClient/src/es/upm/dit/cnvr/server/ConnectionDispatcher.java b/BankClient/src/es/upm/dit/cnvr/server/ConnectionDispatcher.java index f970d7b..58d2f91 100644 --- a/BankClient/src/es/upm/dit/cnvr/server/ConnectionDispatcher.java +++ b/BankClient/src/es/upm/dit/cnvr/server/ConnectionDispatcher.java @@ -5,7 +5,9 @@ import java.io.DataOutputStream; import java.io.InputStreamReader; import java.io.ObjectInputStream; +import java.net.InetAddress; import java.net.Socket; +import java.net.UnknownHostException; import java.util.Random; import org.apache.zookeeper.ZooKeeper; @@ -60,16 +62,23 @@ public void run () { if (zk.getChildren(rootBarrierOperation, false).size() > 0){ synchronized(ZookeeperObject.getMutexOperate()){ - ZookeeperObject.getMutexOperate().wait(); - + System.out.println("He hecho wait con el mutexOperate (en ConnectionDispatcher.java): " + System.identityHashCode(ZookeeperObject.getMutexOperate())); + ZookeeperObject.getMutexOperate().wait(); + } } transaction = (Transaction) inFromClient.readObject(); + try { + String hostname = InetAddress.getLocalHost().getHostName(); + transaction.setHostname(hostname); + } catch (UnknownHostException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } BankClient bc = transaction.getBankClient(); - //TODO: Deberiamos meter comprobaciones para que si la operacion no la realiza bien que no cree los nodos de operaciones if (transaction.getOperation().equals(OperationEnum.CREATE_CLIENT)){ - bc.setAccount(generateId(2)); + bc.setAccount(generateId(5)); status = db.createClient(bc); transaction.setBankClient(bc); transaction.setStatus(status); @@ -88,7 +97,6 @@ public void run () { } } - //TODO: Quitar en ProcessOperation, no es necesario if (transaction.getOperation().equals(OperationEnum.READ_CLIENT)){ if (bc.getAccount() != "0") { bc = db.readAccount(bc.getAccount()); @@ -107,6 +115,13 @@ public void run () { } } + if (transaction.getOperation().equals(OperationEnum.SHOW_ALL)){ + + transaction.setClientdb(db);; + transaction.setStatus(ServiceStatus.OK); + + } + if(es.upm.dit.cnvr.client.ClientApp.debug){ System.out.println("Debug operation"); System.out.println("Connection Dispatcher"); @@ -131,13 +146,13 @@ public void run () { try { //id ++; - System.out.println("Comnection " + id + ": connection closed"); + System.out.println("Connection " + id + ": connection closed"); connection.close(); } catch (Exception e) { e.printStackTrace(); } + System.out.println("FIN CONNECTION DISPATCHER"); } - //TODO Change in the method put of HashMap -> private static String generateId(int bloqDigits){ Random random = new Random(); StringBuilder accountId = new StringBuilder(); diff --git a/BankClient/src/es/upm/dit/cnvr/server/ConnectionDispatcherTest.java b/BankClient/src/es/upm/dit/cnvr/server/ConnectionDispatcherTest.java new file mode 100644 index 0000000..fdd005d --- /dev/null +++ b/BankClient/src/es/upm/dit/cnvr/server/ConnectionDispatcherTest.java @@ -0,0 +1,159 @@ +package es.upm.dit.cnvr.server; + + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.io.ObjectInputStream; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Random; + +import org.apache.zookeeper.ZooKeeper; + +import es.upm.dit.cnvr.model.BankClient; +import es.upm.dit.cnvr.model.ClientDB; +import es.upm.dit.cnvr.model.OperationEnum; +import es.upm.dit.cnvr.model.ServiceStatus; +import es.upm.dit.cnvr.model.Transaction; +import es.upm.dit.cnvr.model.ServiceStatus; + +public class ConnectionDispatcherTest extends Thread { + + private Transaction transaction; + private Socket connection; + private ObjectInputStream inFromClient; + private DataOutputStream outToClient; + private ClientDB db; + private int id; + private ZookeeperObject zkobject; + private Operate operate; + private ZooKeeper zk = ZookeeperObject.getZk(); + private static String rootBarrierOperation = "/boperation"; + private Transaction transactiontest; + + /** + * Constructor + * @param id The identifier of the connection + * @param connection The connection handle for sending a message to the client + * @param db The database of clients + * @param zkobject The object that administer zookeeper + * @param operate The object that create the znodes of the operations + */ + public ConnectionDispatcherTest(int id, ClientDB db, ZookeeperObject zkobject, Operate operate, Transaction transactiontest) { + this.id = id; + this.db = db; + this.zkobject = zkobject; + this.operate = operate; + this.transactiontest = transactiontest; + } + + public void run () { + + Handler handler; + int sequence = 0; + ServiceStatus status = null; + + try { + System.out.println("ConnHandler " + id + ": socket waiting messages."); + + //while (true) { + if (zk.getChildren(rootBarrierOperation, false).size() > 0){ + + synchronized(ZookeeperObject.getMutexOperate()){ + System.out.println("He hecho wait con el mutexOperate (en ConnectionDispatcher.java): " + System.identityHashCode(ZookeeperObject.getMutexOperate())); + ZookeeperObject.getMutexOperate().wait(); + + } + } + + transaction = transactiontest; + BankClient bc = transaction.getBankClient(); + if (transaction.getOperation().equals(OperationEnum.CREATE_CLIENT)){ + bc.setAccount(generateId(5)); + status = db.createClient(bc); + transaction.setBankClient(bc); + transaction.setStatus(status); + if (status.equals(ServiceStatus.OK)){ + operate.operation(transaction); + operate.setPersonalCounter(operate.getPersonalCounter()+1); + } + } + + if (transaction.getOperation().equals(OperationEnum.DELETE_CLIENT)){ + status = db.deleteClient(bc.getAccount(),bc.getClientName()); + transaction.setStatus(status); + if (status.equals(ServiceStatus.OK)){ + operate.operation(transaction); + operate.setPersonalCounter(operate.getPersonalCounter()+1); + } + } + + if (transaction.getOperation().equals(OperationEnum.READ_CLIENT)){ + if (bc.getAccount() != "0") { + bc = db.readAccount(bc.getAccount()); + transaction.setBankClient(bc); + transaction.setStatus(ServiceStatus.OK); + } + status = ServiceStatus.OK; + } + + if (transaction.getOperation().equals(OperationEnum.UPDATE_CLIENT)){ + status = db.update(bc.getAccount(), bc.getBalance()); + transaction.setStatus(status); + if (status.equals(ServiceStatus.OK)){ + operate.operation(transaction); + operate.setPersonalCounter(operate.getPersonalCounter()+1); + } + } + + if (transaction.getOperation().equals(OperationEnum.SHOW_ALL)){ + + transaction.setClientdb(db);; + transaction.setStatus(ServiceStatus.OK); + + } + + if(es.upm.dit.cnvr.client.ClientApp.debug){ + System.out.println("Debug operation"); + System.out.println("Connection Dispatcher"); + System.out.println("Operation: " + transaction.getOperation()); + System.out.println("Account ID: " + transaction.getBankClient().getAccount()); + System.out.println("Client Name: " + transaction.getBankClient().getClientName()); + System.out.println("Balance: " + transaction.getBankClient().getBalance()); + + } + + sequence ++; + //} + } + catch (NullPointerException e) { + System.out.println("Exception. Connection " + id + " Connection closed"); + } + catch (Exception e) { + System.out.println(e); + } + + try { + //id ++; + System.out.println("Connection " + id + ": connection closed"); + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println("FIN CONNECTION DISPATCHER"); + } + private static String generateId(int bloqDigits){ + Random random = new Random(); + StringBuilder accountId = new StringBuilder(); + accountId.append("EB32-"); + for(int i=0;i listBarriersP = null; private int npBarriers = 0; - private String rootBarrier = "/b1"; + private String rootBarrier = "/boperation"; private ZooKeeper zk; private Watcher barrierWatcherP; private Integer mutex; @@ -36,8 +36,6 @@ public void run() { mutex.wait(); } listBarriersP = zk.getChildren(rootBarrier, barrierWatcherP, s); - npBarriers ++; - //System.out.println("Process Barrier. NBarriers: " + npBarriers); } catch (Exception e) { System.out.println("Unexpected Exception process barrier"); break; diff --git a/BankClient/src/es/upm/dit/cnvr/server/ProcessMember.java b/BankClient/src/es/upm/dit/cnvr/server/ProcessMember.java index 0ba76bd..0f06d93 100644 --- a/BankClient/src/es/upm/dit/cnvr/server/ProcessMember.java +++ b/BankClient/src/es/upm/dit/cnvr/server/ProcessMember.java @@ -18,64 +18,23 @@ public class ProcessMember extends Thread{ private ZooKeeper zk; private Watcher memberWatcherP; private Integer mutex; - private String leader = ""; private String myId = null; - private String rootBarrier = "/b1"; - private Integer mutexBarrier; - public ProcessMember(ZooKeeper zk, Watcher memberWatcherP, Integer mutex, String myId, Integer mutexBarrier) { + public ProcessMember(ZooKeeper zk, Watcher memberWatcherP, Integer mutex, String myId) { this.zk = zk; this.memberWatcherP = memberWatcherP; this.mutex = mutex; - this.mutexBarrier = mutexBarrier; this.myId = myId; } - private void leaderElection(List list) { - Barrier b = new Barrier(zk, rootBarrier, list.size(), mutexBarrier); - try { - boolean flag = b.enter(); - System.out.println("Flag es: " + flag); - System.out.println( - "Entered barrier. There are " + list.size() + " members. They are going to wait in the barrier"); - if (!flag) - System.out.println("Error when entering the barrier"); - } catch (KeeperException e) { - } catch (InterruptedException e) { - - } - - // Election - Collections.sort(list); - leader = list.get(0); - if (leader.equals(myId)) { - System.out.println("****You are the leader****"); - } else { - System.out.println("The process " + leader + " is the leader"); - } - - try { - b.leave(); - } catch (KeeperException e) { - System.out.println(e.toString()); - } catch (InterruptedException e) { - System.out.println(e.toString()); - } - System.out.println("Left barrier"); - - } public void printListMembers(List list) { - leaderElection(list); System.out.println("Remaining # members:" + list.size()); System.out.print("The active members are: "); for (Iterator iterator = list.iterator(); iterator.hasNext();) { String string = (String) iterator.next(); - if (leader.equals(string)) { - System.out.print("(L) " + string + ", "); - } else { - System.out.print(string + ", "); - } + System.out.print(string + ", "); + } System.out.println(); System.out.println("---------------------------------------------------"); diff --git a/BankClient/src/es/upm/dit/cnvr/server/ProcessOperation.java b/BankClient/src/es/upm/dit/cnvr/server/ProcessOperation.java index 4cb8c29..a734cf4 100644 --- a/BankClient/src/es/upm/dit/cnvr/server/ProcessOperation.java +++ b/BankClient/src/es/upm/dit/cnvr/server/ProcessOperation.java @@ -23,7 +23,7 @@ public class ProcessOperation extends Thread{ private String rootOperation = "/operation"; private String rootMember = "/members"; private ZooKeeper zk; - private Watcher counterWatcherP; + private Watcher operationWatcherP; private Integer mutex; private Operate operate; private Integer mutexBarrier; @@ -32,9 +32,9 @@ public class ProcessOperation extends Thread{ private Transaction transaction; private BankClient bc; - public ProcessOperation(ZooKeeper zk, Watcher counterWatcherP, Integer mutex, Integer mutexBarrier, Operate operate) { + public ProcessOperation(ZooKeeper zk, Watcher operationWatcherP, Integer mutex, Integer mutexBarrier, Operate operate) { this.zk = zk; - this.counterWatcherP = counterWatcherP; + this.operationWatcherP = operationWatcherP; this.mutex = mutex; this.operate = operate; this.mutexBarrier = mutexBarrier; @@ -48,27 +48,36 @@ public Transaction readData(byte[] data) throws IOException, ClassNotFoundExcept // String string = new String(data, StandardCharsets.UTF_8); // return string; } - //TODO: Esto todavia no se ha mirado. @Override public void run() { Stat s = null; + while (true) { try { synchronized (mutex) { mutex.wait(); } + Stat stat = null; + try { + stat = zk.exists("/boperationleave", false); + if(stat != null){ + zk.delete("/boperationleave", 0); + } + } catch (KeeperException e1) { + e1.printStackTrace(); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } List listOperation = zk.getChildren(rootOperation, false, null); int size = listOperation.size(); List listMembers = zk.getChildren(rootMember, false, null); Barrier b = new Barrier(zk, rootBarrier, listMembers.size(), mutexBarrier); - System.out.println("La lista del contador es " + size); //WATCHER Habría que hacerlo en el watcher + zk.getChildren(rootOperation, operationWatcherP, s); b.enter(); if (operate.getPersonalCounter() < size){ System.out.println("DESACTUALIZADO"); - ///XXX: Voy a cambiar de posicion b.enter y b.leave de dentro del if afuera porque va a ser necesario que la operacion primera la haga en otro lado, y entonces estara al dia y no entrara a la barrera bloqueando a los demas int numOp = size-operate.getPersonalCounter(); - System.out.println("Tiene que hacer " + numOp + " cuentas"); try { listOperation = zk.getChildren(rootOperation, false); } catch (KeeperException | InterruptedException e) { @@ -79,21 +88,20 @@ public void run() { byte[] op = new byte[0]; try { op = zk.getData(rootOperation+"/" +listOperation.get(i),false, null); - //TODO: Cambiar esto por las mierdas verdaderas (Operaciones verdaderas) transaction = readData(op); bc = transaction.getBankClient(); - if (readData(op).equals(OperationEnum.CREATE_CLIENT)){ + if (readData(op).getOperation().equals(OperationEnum.CREATE_CLIENT)){ db.createClient(bc); operate.setPersonalCounter(operate.getPersonalCounter()+1); } - if (readData(op).equals(OperationEnum.DELETE_CLIENT)){ + if (readData(op).getOperation().equals(OperationEnum.DELETE_CLIENT)){ db.deleteClient(bc.getAccount(),bc.getClientName()); operate.setPersonalCounter(operate.getPersonalCounter()+1); } - if (readData(op).equals(OperationEnum.UPDATE_CLIENT)){ + if (readData(op).getOperation().equals(OperationEnum.UPDATE_CLIENT)){ db.update(bc.getAccount(), bc.getBalance()); operate.setPersonalCounter(operate.getPersonalCounter()+1); } @@ -101,8 +109,8 @@ public void run() { } catch (KeeperException | InterruptedException e) { e.printStackTrace(); } - operate.setPersonalCounter(operate.getPersonalCounter()+1); - System.out.println("La operacion que tiene que realizar es: " + readData(op).getOperation().toString()); + //operate.setPersonalCounter(operate.getPersonalCounter()+1); + System.out.println("The operation to do is: " + readData(op).getOperation().toString()); } try { listOperation = zk.getChildren(rootOperation, true, null); @@ -111,18 +119,16 @@ public void run() { } catch (InterruptedException e) { e.printStackTrace(); } - - zk.getChildren(rootOperation, counterWatcherP, s); System.out.println("Left counterbarrier"); - } + } b.leave(); - synchronized(ZookeeperObject.getMutexOperate()){ - ZookeeperObject.getMutexOperate().notify(); - } - +// synchronized(ZookeeperObject.getMutexOperate()){ +// ZookeeperObject.getMutexOperate().notify(); +// } + zk.getChildren(rootOperation, operationWatcherP, s); } catch (Exception e) { - System.out.println("Unexpected Exception process member"); + System.out.println("Unexpected Exception process member"+e.toString()); break; } } diff --git a/BankClient/src/es/upm/dit/cnvr/server/TCPServer.java b/BankClient/src/es/upm/dit/cnvr/server/TCPServer.java index 905003e..4b15a22 100644 --- a/BankClient/src/es/upm/dit/cnvr/server/TCPServer.java +++ b/BankClient/src/es/upm/dit/cnvr/server/TCPServer.java @@ -18,9 +18,9 @@ public static void main(String[] args) throws Exception { zkobject.configure(); Operate operate = zkobject.getOperate(); - ServerSocket welcomeSocket = new ServerSocket(6789); + ServerSocket welcomeSocket = new ServerSocket(6788); + - while (true) { try { connectionSocket = welcomeSocket.accept(); diff --git a/BankClient/src/es/upm/dit/cnvr/server/TCPServerTest.java b/BankClient/src/es/upm/dit/cnvr/server/TCPServerTest.java new file mode 100644 index 0000000..fc75f82 --- /dev/null +++ b/BankClient/src/es/upm/dit/cnvr/server/TCPServerTest.java @@ -0,0 +1,43 @@ +package es.upm.dit.cnvr.server; + +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; + +import es.upm.dit.cnvr.model.BankClient; +import es.upm.dit.cnvr.model.ClientDB; +import es.upm.dit.cnvr.model.OperationEnum; +import es.upm.dit.cnvr.model.Transaction; +import es.upm.dit.cnvr.server.ZookeeperObject; + + +public class TCPServerTest { + + public static void main(String[] args) throws Exception { + + Socket connectionSocket; + int id = 0; + ClientDB db = ClientDB.getInstance(); + ZookeeperObject zkobject = new ZookeeperObject(); + zkobject.configure(); + Operate operate = zkobject.getOperate(); + int loop = 100; + Transaction transaction; + + for (int i=0; i<=loop; i++) { + try { + Thread.sleep(750); + transaction = new Transaction(OperationEnum.CREATE_CLIENT, new BankClient("0", "User de prueba", i)); + ConnectionDispatcherTest conHandler = new ConnectionDispatcherTest(id, db, zkobject, operate, transaction); + System.out.println("Get a socket connection"); + conHandler.start(); + System.out.println("Reach after start"); + id++; + } catch (Exception e) { + System.out.println("Closed the socket"); + } + } + //welcomeSocket.close(); + } + +} diff --git a/BankClient/src/es/upm/dit/cnvr/server/ZookeeperObject.java b/BankClient/src/es/upm/dit/cnvr/server/ZookeeperObject.java index 8ae7fca..992fd34 100644 --- a/BankClient/src/es/upm/dit/cnvr/server/ZookeeperObject.java +++ b/BankClient/src/es/upm/dit/cnvr/server/ZookeeperObject.java @@ -1,7 +1,11 @@ package es.upm.dit.cnvr.server; +import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -23,13 +27,11 @@ public class ZookeeperObject implements Watcher{ private static ZooKeeper zk = null; private static String rootMembers = "/members"; - private static String rootBarrier = "/b1"; - private static String rootBarrierOperation = "/boperation"; + private static String rootBarrier = "/boperation"; private static String aMember = "/member-"; private static int nMembers = 0; private static int nBarriers = 0; private static List listMembers = null; - private String leader = ""; private static Integer mutex = -1; @@ -62,7 +64,8 @@ public static Integer getMutexBarrier() { public void configure() { System.out.println("START CONFIGURE"); // This is static. A list of zookeeper can be provided for decide where to connect - String[] hosts = {"138.4.31.99:2181", "138.4.31.98:2182"}; + String[] hosts = getIps().toArray(new String[0]); + //String[] hosts = {"138.4.31.99:2181", "138.4.31.117:2182"}; // Select a random zookeeper server Random rand = new Random(); @@ -111,7 +114,7 @@ public void configure() { //myId = myId.replace(rootMembers + "/", ""); // false. Debe esperar a arrancar el barrir listMembers = getZk().getChildren(rootMembers, memberWatcher, s); - printListMembers(listMembers); + //printListMembers(listMembers); //System.out.println("Created znode nember id:"+ myId ); @@ -122,7 +125,7 @@ public void configure() { System.out.println("InterruptedException raised"); } - // Create the /b1 znode + // Create the /boperation znode if (getZk() != null) { try { Stat s = getZk().exists(rootBarrier, false); @@ -145,29 +148,6 @@ public void configure() { System.out.println("Interrupted exception"); } } - // Create the /b1 znode - if (getZk() != null) { - try { - Stat s = getZk().exists(rootBarrierOperation, false); - if (s == null) { - getZk().create(rootBarrierOperation, new byte[0], Ids.OPEN_ACL_UNSAFE, - CreateMode.PERSISTENT); - } - -// getZk().create(rootBarrier, new byte[0], -// Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); - //myId = myId.replace(rootMembers + "/", ""); - // false. Debe esperar a arrancar el barrir - getZk().getChildren(rootBarrierOperation, barrierWatcher, s); - - } catch (KeeperException e) { - System.out - .println("Keeper exception when instantiating queue: " - + e.toString()); - } catch (InterruptedException e) { - System.out.println("Interrupted exception"); - } - } if (getZk() != null) { // Create a folder for members and include this process/server try { @@ -195,7 +175,7 @@ public void configure() { } operate = new Operate(getZk()); try { - getZk().getChildren(rootOperation, counterOperation, null); + getZk().getChildren(rootOperation, operationWatcher, null); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { @@ -204,11 +184,11 @@ public void configure() { } // Create threads - ProcessMember pm = new ProcessMember(getZk(), memberWatcher, mutexMember, myId, mutexBarrier); + ProcessMember pm = new ProcessMember(getZk(), memberWatcher, mutexMember, myId); pm.start(); ProcessBarrier bm = new ProcessBarrier(getZk(), barrierWatcher, mutexBarrier); bm.start(); - ProcessOperation cm = new ProcessOperation(getZk(), counterOperation, mutexOperate, mutexBarrier, operate); + ProcessOperation cm = new ProcessOperation(getZk(), operationWatcher, mutexOperate, mutexBarrier, operate); cm.start(); synchronized (mutexMember) { @@ -239,8 +219,8 @@ public void printListMembers(List list) { public void process(WatchedEvent event) { Stat s = null; - System.out.println("------------------Watcher PROCESS ------------------"); - System.out.println("Member: " + event.getType() + ", " + event.getPath()); + //System.out.println("------------------Watcher PROCESS ------------------"); + //System.out.println("Member: " + event.getType() + ", " + event.getPath()); try { if (event.getPath() == null) { //if (event.getState() == Watcher.Event.KeeperState.SyncConnected) { @@ -341,7 +321,7 @@ else if (event.getPath().equals(rootBarrier)) { } }; - Watcher counterOperation = new Watcher() { + Watcher operationWatcher = new Watcher() { public void process(WatchedEvent event) { Stat s = null; @@ -368,6 +348,7 @@ else if (event.getPath().equals(rootOperation)) { listMembers = getZk().getChildren(rootOperation, false, s); synchronized (mutexOperate) { mutexOperate.notifyAll(); + System.out.println("He hecho notify con el mutexOperate: " + System.identityHashCode(mutexBarrier)); } } else if (event.getPath().equals(rootBarrier)) { @@ -384,6 +365,18 @@ else if (event.getPath().equals(rootBarrier)) { } } }; + + private static ArrayList getIps(){ + ArrayList ips = new ArrayList(); + try { + Files.lines(Paths.get("/root/zookeeperips.txt")).forEach(ips::add); + } catch (IOException e) { + ips.add("127.0.0.1"); + System.out.println("Ips not found. Default: 127.0.0.1"); + e.printStackTrace(); + } + return ips; + } } diff --git a/BankClient/zookeeperips.txt b/BankClient/zookeeperips.txt new file mode 100644 index 0000000..68c8069 --- /dev/null +++ b/BankClient/zookeeperips.txt @@ -0,0 +1,3 @@ +10.1.2.21:2181 +10.1.2.22:2181 +10.1.2.23:2181 \ No newline at end of file