Merge branch 'feat/protocol-parser' into 'main'
Add ProtocolParser to parse RawPacket into PrimitiveRequest using the Tokenizer See merge request cs108-fs26/Gruppe-13!31
This commit was merged in pull request #187.
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.server.network.parser;
|
||||
|
||||
/** Used in the PrimitiveRequest class to store the key of a parameter with its respective value */
|
||||
public record Parameter(String key, String value) {}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.server.network.parser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Created by the ProtocolParser to allow easy access to the request contents */
|
||||
public record PrimitiveRequest(int requestId, String command, List<Parameter> parameters) {}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.server.network.parser;
|
||||
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.RawToken;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.Token;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenClassifier;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.TokenType;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.tokenizer.Tokenizer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/** ProtocolParser, used to parse RawPacket into a PrimitiveRequest */
|
||||
public class ProtocolParser {
|
||||
/**
|
||||
* Parses the payload of the provided RawPacket
|
||||
*
|
||||
* @param packet the RawPacket containing the recieved data
|
||||
* @return created PrimitiveRequest
|
||||
*/
|
||||
public static PrimitiveRequest parse(RawPacket packet) {
|
||||
List<RawToken> rawTokens = Tokenizer.tokenize(packet.payload());
|
||||
List<Token> tokens = TokenClassifier.classify(rawTokens);
|
||||
|
||||
Iterator<Token> iterator = tokens.iterator();
|
||||
String command = readCommand(iterator);
|
||||
List<Parameter> parameters = readParameters(iterator);
|
||||
|
||||
return new PrimitiveRequest(packet.requestId(), command, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the first token, which is ensured to be the command of the request
|
||||
*
|
||||
* @param iterator
|
||||
* @return read command
|
||||
*/
|
||||
private static String readCommand(Iterator<Token> iterator) {
|
||||
Token token = iterator.next();
|
||||
if (token.type() != TokenType.COMMAND) {
|
||||
throw new ProtocolParserException("Expected COMMAND got " + token.type());
|
||||
}
|
||||
|
||||
return token.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over the remaining tokens, calling helperfunctions to validate token type
|
||||
*
|
||||
* @param iterator
|
||||
* @return list containing all parsed parameters
|
||||
*/
|
||||
private static List<Parameter> readParameters(Iterator<Token> iterator) {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
|
||||
try {
|
||||
while (iterator.hasNext()) {
|
||||
Token nextToken = iterator.next();
|
||||
|
||||
if (nextToken.type() == TokenType.EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
String key = readKey(nextToken);
|
||||
readSeperator(iterator.next());
|
||||
String value = readValue(iterator.next());
|
||||
|
||||
parameters.add(new Parameter(key, value));
|
||||
}
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new ProtocolParserException("Ran out of tokens while reading parameter");
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param token the current token
|
||||
* @return
|
||||
*/
|
||||
private static String readKey(Token token) {
|
||||
if (token.type() != TokenType.KEY) {
|
||||
throw new ProtocolParserException("Expected KEY got " + token.type());
|
||||
}
|
||||
|
||||
return token.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param token the current token
|
||||
*/
|
||||
private static void readSeperator(Token token) {
|
||||
if (token.type() != TokenType.SEPARATOR) {
|
||||
throw new ProtocolParserException("Expected SEPARATOR got " + token.type());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param token the current token
|
||||
* @return
|
||||
*/
|
||||
private static String readValue(Token token) {
|
||||
if (token.type() != TokenType.VALUE) {
|
||||
throw new ProtocolParserException("Expected VALUE got " + token.type());
|
||||
}
|
||||
|
||||
return token.value();
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.server.network.parser;
|
||||
|
||||
public class ProtocolParserException extends RuntimeException {
|
||||
public ProtocolParserException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@ package ch.unibas.dmi.dbis.cs108.casono.server.network.sessions;
|
||||
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.events.DisconnectEvent;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.events.EventBus;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.PrimitiveRequest;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.parser.ProtocolParser;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TransportLayer;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
@@ -64,7 +67,11 @@ public class Session implements Runnable {
|
||||
public void run() {
|
||||
while (running) {
|
||||
try {
|
||||
logger.debug("Recieved: {}", transport.read());
|
||||
RawPacket rawPacket = transport.read();
|
||||
logger.debug("Recieved: {}", rawPacket);
|
||||
|
||||
PrimitiveRequest primitiveRequest = ProtocolParser.parse(rawPacket);
|
||||
logger.debug("Parsed request to {}", primitiveRequest);
|
||||
} catch (EOFException e) {
|
||||
logger.info("Client disconnected");
|
||||
eventBus.publish(new DisconnectEvent(id));
|
||||
|
||||
Reference in New Issue
Block a user