mirror of
				https://github.com/klmp200/PQT_Gestionnaire_vente_stock.git
				synced 2025-10-31 09:03:08 +00:00 
			
		
		
		
	Module Server : ajout support nouvelles query; MAJ Javadoc; Suppr TODO
This commit is contained in:
		| @@ -8,22 +8,18 @@ import com.pqt.core.entities.product.LightweightProduct; | ||||
| import com.pqt.core.entities.product.Product; | ||||
| import com.pqt.core.entities.product.ProductUpdate; | ||||
| import com.pqt.core.entities.sale.Sale; | ||||
| import com.pqt.core.entities.server_config.ServerConfig; | ||||
| import com.pqt.core.entities.user_account.Account; | ||||
| import com.pqt.core.entities.user_account.AccountLevel; | ||||
| import com.pqt.server.exception.ServerQueryException; | ||||
| import com.pqt.server.module.account.AccountService; | ||||
| import com.pqt.server.module.client.ClientService; | ||||
| import com.pqt.server.module.sale.SaleService; | ||||
| import com.pqt.server.module.state.ServerStateService; | ||||
| import com.pqt.server.module.statistics.StatisticsService; | ||||
| import com.pqt.server.module.stock.StockService; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.*; | ||||
|  | ||||
| //TODO ajouter des messages d'erreur spécifiques pour les NullPointerException si le param du message vaut null | ||||
| //TODO mettre à jour la liste des query supportées lorsque la version du serveur sera proche de la release | ||||
| //TODO ne pas oublier de préciser le niveau de permission requis pour chaque requête | ||||
| //TODO Paramétrer les supports de query et leurs permissions via un meilleur système (config file, etc ...) | ||||
| /** | ||||
|  * Implémentation de l'interface {@link IMessageHandler}. Cette classe définit le gestionnaire de message par défaut du | ||||
| @@ -31,12 +27,20 @@ import java.util.Map; | ||||
|  * <p/> | ||||
|  * Liste des requêtes supportées :<br/> | ||||
|  *  <ul> | ||||
|  * | ||||
|  *      <li>QUERY_STOCK (WAITER)</li> | ||||
|  *      <li>QUERY_SALE (WAITER)</li> | ||||
|  *      <li>QUER_STAT (WAITER)</li> | ||||
|  *      <li>QUERY_UPDATE (MASTER)</li> | ||||
|  *      <li>QUERY_ACCOUNT_LIST (NONE)</li> | ||||
|  *      <li>QUERY_CONNECT_ACCOUNT (NONE)</li> | ||||
|  *      <li>QUERY_PING (NONE)</li> | ||||
|  *      <li>QUERY_CONFIG_LIST (NONE)</li> | ||||
|  *  </ul> | ||||
|  * <p/> | ||||
|  * Liste des requêtes non-supportées :<br/> | ||||
|  *  <ul> | ||||
|  * | ||||
|  *      <li>QUERY_REVERT_SALE</li> | ||||
|  *      <li>QUERY_LAST_SALES_LIST</li> | ||||
|  *  </ul> | ||||
|  * @see IMessageHandler | ||||
|  * @version 1.0 | ||||
| @@ -72,24 +76,26 @@ public class SimpleMessageHandler implements IMessageHandler { | ||||
|  | ||||
|         manager = new MessageManager(); | ||||
|  | ||||
|         //TODO ajouter support des query de connexion de compte utilisateur | ||||
|         manager.support(MessageType.QUERY_STOCK, (message)->{ | ||||
|         /* | ||||
|         WAITER-restricted queries | ||||
|          */ | ||||
|         manager.supportForConnectedAccounts(MessageType.QUERY_STOCK, (message)->{ | ||||
|             Map<String, String> fields = new HashMap<>(); | ||||
|             fields.put("stock", messageToolFactory.getListFormatter(Product.class).format(stockService.getProductList())); | ||||
|             return new Message(MessageType.MSG_STOCK, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|         }, AccountLevel.WAITER); | ||||
|         manager.support(MessageType.QUERY_SALE, (message)->{ | ||||
|         manager.supportForConnectedAccounts(MessageType.QUERY_SALE, (message)->{ | ||||
|             Map<String, String> fields = new HashMap<>(); | ||||
|             try { | ||||
|                 long saleId = saleService.submitSale(messageToolFactory.getObjectParser(Sale.class).parse(message.getField("sale"))); | ||||
|                 fields.put("saleId", Long.toString(saleId)); | ||||
|                 return new Message(MessageType.ACK_SALE, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|             }catch(ServerQueryException | NullPointerException e){ | ||||
|             }catch(NullPointerException e){ | ||||
|                 fields.put(header_ref_query, e.toString()); | ||||
|                 return new Message(MessageType.REFUSED_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|             } | ||||
|         }, AccountLevel.WAITER); | ||||
|         manager.support(MessageType.QUERY_STAT, (message)->{ | ||||
|         manager.supportForConnectedAccounts(MessageType.QUERY_STAT, (message)->{ | ||||
|             Map<String, String> fields = new HashMap<>(); | ||||
|             fields.put("total_sale_worth", Double.toString(statisticsService.getTotalSaleWorth())); | ||||
|             fields.put("total_sale_amount", Integer.toString(statisticsService.getTotalAmountSale())); | ||||
| @@ -102,7 +108,11 @@ public class SimpleMessageHandler implements IMessageHandler { | ||||
|  | ||||
|             return new Message(MessageType.MSG_STAT, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|         }, AccountLevel.WAITER); | ||||
|         manager.support(MessageType.QUERY_UPDATE, (message)->{ | ||||
|  | ||||
|         /* | ||||
|         MASTER-restricted queries | ||||
|          */ | ||||
|         manager.supportForConnectedAccounts(MessageType.QUERY_UPDATE, (message)->{ | ||||
|             try{ | ||||
|                 List<ProductUpdate> updates = messageToolFactory.getListParser(ProductUpdate.class).parse(message.getField("updates")); | ||||
|                 stockService.applyUpdateList(updates); | ||||
| @@ -113,19 +123,82 @@ public class SimpleMessageHandler implements IMessageHandler { | ||||
|                 return new Message(MessageType.ERROR_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|             } | ||||
|         }, AccountLevel.MASTER); | ||||
|         /* | ||||
|         manager.support(MessageType.QUERY_REVERT_SALE, (message)->{ | ||||
|  | ||||
|             try{ | ||||
|                 saleService.submitSaleRevert(messageToolFactory.getObjectParser(Long.class).parse(message.getField("saleId"))); | ||||
|                 return new Message(MessageType.ACK_REVERT_SALE, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, null); | ||||
|             }catch(ServerQueryException | NullPointerException e){ | ||||
|                 Map<String, String> fields = new HashMap<>(); | ||||
|                 fields.put(header_err_query, e.toString()); | ||||
|                 return new Message(MessageType.ERROR_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|             } | ||||
|          }, AccountLevel.MASTER); | ||||
|         /* | ||||
|         Queries without account connection requirements | ||||
|          */ | ||||
|         manager.support(MessageType.QUERY_ACCOUNT_LIST, (message)->{ | ||||
|             Map<String, String> fields = new HashMap<>(); | ||||
|             fields.put("accounts", messageToolFactory.getListFormatter(Account.class).format(accountService.getAccountList())); | ||||
|             return new Message(MessageType.MSG_ACCOUNT_LIST, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|         }, AccountLevel.getLowest(), false); | ||||
|         manager.support(MessageType.QUERY_CONNECT_ACCOUNT, (message)->{ | ||||
|             final String desiredStateFieldHeader = "desired_state", | ||||
|                     accountCredentialsFieldHeader = "account"; | ||||
|  | ||||
|             if(message.getFields().containsKey(desiredStateFieldHeader)){ | ||||
|                 if(message.getFields().containsKey(accountCredentialsFieldHeader)){ | ||||
|                     boolean desiredState = messageToolFactory.getObjectParser(Boolean.class).parse(message.getField(desiredStateFieldHeader)); | ||||
|                     Account accountCredentials = messageToolFactory.getObjectParser(Account.class).parse(message.getField(accountCredentialsFieldHeader)); | ||||
|  | ||||
|                     if(accountService.submitAccountCredentials(accountCredentials, desiredState)){ | ||||
|                         return new Message(MessageType.ACK_CONNECT_ACCOUNT, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, null); | ||||
|                     }else{ | ||||
|                         Map<String, String> fields = new HashMap<>(); | ||||
|                         fields.put(header_ref_query, "Impossible d'effectuer l'action : identifiants invalides ou état désiré déjà atteint"); | ||||
|  | ||||
|                         return new Message(MessageType.REFUSED_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|                     } | ||||
|                 }else{ | ||||
|                     return getMissingArgumentQueryReplyMessage(message, accountCredentialsFieldHeader); | ||||
|                 } | ||||
|             }else{ | ||||
|                 return getMissingArgumentQueryReplyMessage(message, desiredStateFieldHeader); | ||||
|             } | ||||
|         }, AccountLevel.getLowest(), false); | ||||
|         manager.support(MessageType.QUERY_PING, (message)->new Message(MessageType.ACK_PING, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, null), AccountLevel.getLowest(), false); | ||||
|         manager.support(MessageType.QUERY_CONFIG_LIST, (message)->{ | ||||
|             Map<String, String> fields = new HashMap<>(); | ||||
|             fields.put("config", messageToolFactory.getObjectFormatter(ServerConfig.class).format(serverStateService.getConfig())); | ||||
|             return new Message(MessageType.MSG_CONFIG_LIST, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|         }, AccountLevel.getLowest(), false); | ||||
|     } | ||||
|  | ||||
|     private Message getUnsupportedQueryReplyMessage(Message message){ | ||||
|         final String msg_ref_unsupported_query = "Ce type de requêtes n'est actuellement pas supportée par ce serveur."; | ||||
|         Map<String, String> fields = new HashMap<>(); | ||||
|         fields.put(header_ref_query, msg_ref_unsupported_query); | ||||
|  | ||||
|         return new Message(MessageType.REFUSED_QUERY, | ||||
|                 serverStateService.getServer(), | ||||
|                 message.getEmitter(), | ||||
|                 message.getUser(), | ||||
|                 message, | ||||
|                 fields); | ||||
|     } | ||||
|  | ||||
|     private Message getMissingArgumentQueryReplyMessage(Message message, String missingArgumentHeader){ | ||||
|         Map<String, String> fields = new HashMap<>(); | ||||
|         fields.put(header_err_query, "The following required header is missing : "+missingArgumentHeader); | ||||
|  | ||||
|         return new Message(MessageType.ERROR_QUERY, | ||||
|                 serverStateService.getServer(), | ||||
|                 message.getEmitter(), | ||||
|                 message.getUser(), | ||||
|                 message, | ||||
|                 fields); | ||||
|     } | ||||
|  | ||||
|     private Message getExceptionOccuredQueryReplyMessage(Message message, Exception exception){ | ||||
|         Map<String, String> fields = new HashMap<>(); | ||||
|         fields.put(header_err_query, exception.getMessage()); | ||||
|  | ||||
|         return new Message(MessageType.ERROR_QUERY, | ||||
|                 serverStateService.getServer(), | ||||
|                 message.getEmitter(), | ||||
|                 message.getUser(), | ||||
|                 message, | ||||
|                 fields); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -133,20 +206,25 @@ public class SimpleMessageHandler implements IMessageHandler { | ||||
|  | ||||
|         Map<String, String> fields = new HashMap<>(); | ||||
|  | ||||
|         if(!isAccountRegisteredAndConnected(message)){ | ||||
|             fields.put(header_ref_query, "Compte utilisateur inconnu"); | ||||
|             return new Message(MessageType.REFUSED_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|         } | ||||
|         if(!checkAccountPermission(message)){ | ||||
|             fields.put(header_ref_query, "Compte utilisateur avec permission trop faible"); | ||||
|             return new Message(MessageType.REFUSED_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|         } | ||||
|         if(manager.contains(message.getType())){ | ||||
|             return manager.getProcess(message.getType()).execute(message); | ||||
|             if(manager.isQueryRestrictedToConnectedAccount(message.getType())) { | ||||
|                 if (!isAccountRegisteredAndConnected(message)) { | ||||
|                     fields.put(header_ref_query, "Compte utilisateur inconnu ou déconnecté."); | ||||
|                     return new Message(MessageType.REFUSED_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|                 } | ||||
|                 if (!checkAccountPermission(message)) { | ||||
|                     fields.put(header_ref_query, "Compte utilisateur avec permission trop faible"); | ||||
|                     return new Message(MessageType.REFUSED_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|                 } | ||||
|             } | ||||
|             try{ | ||||
|                 return manager.getProcess(message.getType()).execute(message); | ||||
|             }catch(Exception e){ | ||||
|                 return getExceptionOccuredQueryReplyMessage(message, e); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         fields.put(header_err_query, "Type requête non pris en charge par ce serveur"); | ||||
|         return new Message(MessageType.ERROR_QUERY, serverStateService.getServer(), message.getEmitter(), message.getUser(), message, fields); | ||||
|         return getUnsupportedQueryReplyMessage(message); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -156,30 +234,97 @@ public class SimpleMessageHandler implements IMessageHandler { | ||||
|         Message execute(Message request); | ||||
|     } | ||||
|  | ||||
|     private class MessageManager{ | ||||
|         private Map<MessageType, IMessageProcess> processes; | ||||
|         private Map<MessageType, AccountLevel> levels; | ||||
|     private class MessageTypeEntry{ | ||||
|         private MessageType type; | ||||
|         private IMessageProcess process; | ||||
|         private AccountLevel level; | ||||
|         private boolean connectedAccountRestriction; | ||||
|  | ||||
|         MessageManager(){ | ||||
|             processes = new HashMap<>(); | ||||
|             levels = new HashMap<>(); | ||||
|         MessageTypeEntry(MessageType type, IMessageProcess process, AccountLevel level, boolean connectedAccountRestriction) { | ||||
|             this.type = type; | ||||
|             this.process = process; | ||||
|             this.level = level; | ||||
|             this.connectedAccountRestriction = connectedAccountRestriction; | ||||
|         } | ||||
|  | ||||
|         void support(MessageType type, IMessageProcess process, AccountLevel permissionLevel){ | ||||
|             processes.put(type, process); | ||||
|             levels.put(type, permissionLevel); | ||||
|         IMessageProcess getProcess() { | ||||
|             return process; | ||||
|         } | ||||
|  | ||||
|         AccountLevel getLevel() { | ||||
|             return level; | ||||
|         } | ||||
|  | ||||
|         boolean isConnectedAccountRestriction() { | ||||
|             return connectedAccountRestriction; | ||||
|         } | ||||
|  | ||||
|         boolean matches(MessageType type){ | ||||
|             return type.equals(this.type); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public boolean equals(Object o) { | ||||
|             if (this == o) return true; | ||||
|             if (o == null || getClass() != o.getClass()) return false; | ||||
|  | ||||
|             MessageTypeEntry that = (MessageTypeEntry) o; | ||||
|  | ||||
|             return connectedAccountRestriction == that.connectedAccountRestriction && type == that.type && process.equals(that.process) && level == that.level; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public int hashCode() { | ||||
|             int result = type.hashCode(); | ||||
|             result = 31 * result + process.hashCode(); | ||||
|             result = 31 * result + level.hashCode(); | ||||
|             result = 31 * result + (connectedAccountRestriction ? 1 : 0); | ||||
|             return result; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private class MessageManager{ | ||||
|         private Set<MessageTypeEntry> entries; | ||||
|  | ||||
|         MessageManager(){ | ||||
|             entries = new HashSet<>(); | ||||
|         } | ||||
|  | ||||
|         void supportForConnectedAccounts(MessageType type, IMessageProcess process, AccountLevel permissionLevel){ | ||||
|             support(type, process, permissionLevel, true); | ||||
|         } | ||||
|  | ||||
|         void support(MessageType type, IMessageProcess process, AccountLevel permissionLevel, boolean accountConnectionRequired){ | ||||
|             entries.add(new MessageTypeEntry(type, process, permissionLevel, accountConnectionRequired)); | ||||
|         } | ||||
|  | ||||
|         private MessageTypeEntry getFirstMatch(MessageType type){ | ||||
|             return entries.stream().filter(entry->entry.matches(type)).findFirst().orElse(null); | ||||
|         } | ||||
|  | ||||
|         IMessageProcess getProcess(MessageType messageType){ | ||||
|             return processes.get(messageType); | ||||
|              MessageTypeEntry entry = getFirstMatch(messageType); | ||||
|              if(entry!=null) | ||||
|                  return entry.getProcess(); | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         AccountLevel getLevel(MessageType messageType){ | ||||
|             return levels.get(messageType); | ||||
|             MessageTypeEntry entry = getFirstMatch(messageType); | ||||
|             if(entry!=null) | ||||
|                 return entry.getLevel(); | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         boolean contains(MessageType type) { | ||||
|             return processes.containsKey(type); | ||||
|             return getFirstMatch(type)!=null; | ||||
|         } | ||||
|  | ||||
|         boolean isQueryRestrictedToConnectedAccount(MessageType type) { | ||||
|             MessageTypeEntry entry = getFirstMatch(type); | ||||
|             return entry != null && entry.isConnectedAccountRestriction(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| package com.pqt.server.module.state; | ||||
|  | ||||
| import com.pqt.core.entities.members.DataServer; | ||||
| import com.pqt.core.entities.server_config.ConfigFields; | ||||
| import com.pqt.core.entities.server_config.ServerConfig; | ||||
|  | ||||
| import java.util.Date; | ||||
|  | ||||
| @@ -16,10 +18,16 @@ public class ServerStateService { | ||||
|  | ||||
| 	private ServerState serverState; | ||||
| 	private DataServer server; | ||||
| 	private ServerConfig config; | ||||
|  | ||||
| 	public ServerStateService() { | ||||
| 	    this.server = new DataServer(); | ||||
| 	    this.serverState = new ServerState(); | ||||
| 	    this.config = new ServerConfig( | ||||
| 	    		ConfigFields.ALLOW_ACCOUNT_CONNECT, | ||||
| 				ConfigFields.ALLOW_SALE_COMMIT, | ||||
| 				ConfigFields.ALLOW_STOCK_UPDATE, | ||||
| 				ConfigFields.ALLOW_STOCK_VIEW); | ||||
|  | ||||
| 	    //TODO config adresse IP | ||||
|         //this.com.pqt.server.setAddress(...); | ||||
| @@ -49,4 +57,7 @@ public class ServerStateService { | ||||
| 		return serverState.copy(); | ||||
| 	} | ||||
|  | ||||
| 	public ServerConfig getConfig() { | ||||
| 		return config; | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user