diff --git a/Workspace/server/src/main/WEB-INF/classes/com/pqt/server/controller/SimpleMessageHandler.java b/Workspace/server/src/main/WEB-INF/classes/com/pqt/server/controller/SimpleMessageHandler.java
index 182100a5..e60176bd 100644
--- a/Workspace/server/src/main/WEB-INF/classes/com/pqt/server/controller/SimpleMessageHandler.java
+++ b/Workspace/server/src/main/WEB-INF/classes/com/pqt/server/controller/SimpleMessageHandler.java
@@ -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;
*
* Liste des requêtes supportées :
*
- *
+ * - QUERY_STOCK (WAITER)
+ * - QUERY_SALE (WAITER)
+ * - QUER_STAT (WAITER)
+ * - QUERY_UPDATE (MASTER)
+ * - QUERY_ACCOUNT_LIST (NONE)
+ * - QUERY_CONNECT_ACCOUNT (NONE)
+ * - QUERY_PING (NONE)
+ * - QUERY_CONFIG_LIST (NONE)
*
*
* Liste des requêtes non-supportées :
*
- *
+ * - QUERY_REVERT_SALE
+ * - QUERY_LAST_SALES_LIST
*
* @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 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 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 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 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 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 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 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 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 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 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 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 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 processes;
- private Map 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 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();
}
}
diff --git a/Workspace/server/src/main/WEB-INF/classes/com/pqt/server/module/state/ServerStateService.java b/Workspace/server/src/main/WEB-INF/classes/com/pqt/server/module/state/ServerStateService.java
index 6a49d4b8..3e32ed93 100644
--- a/Workspace/server/src/main/WEB-INF/classes/com/pqt/server/module/state/ServerStateService.java
+++ b/Workspace/server/src/main/WEB-INF/classes/com/pqt/server/module/state/ServerStateService.java
@@ -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;
+ }
}