diff --git a/Client/vs_lab02_grpc_log_service/.vscode/settings.json b/Client/vs_lab02_grpc_log_service/.vscode/settings.json
new file mode 100644
index 0000000..07498ee
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+ "java.compile.nullAnalysis.mode": "disabled",
+ "java.configuration.updateBuildConfiguration": "automatic"
+}
\ No newline at end of file
diff --git a/Client/vs_lab02_grpc_log_service/pom.xml b/Client/vs_lab02_grpc_log_service/pom.xml
new file mode 100644
index 0000000..2155483
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/pom.xml
@@ -0,0 +1,91 @@
+
+
+ 4.0.0
+
+ vslab2.src
+ labor2vs
+ 1.0-SNAPSHOT
+
+
+
+ io.grpc
+ grpc-netty-shaded
+ 1.63.0
+ runtime
+
+
+ io.grpc
+ grpc-protobuf
+ 1.63.0
+
+
+ io.grpc
+ grpc-stub
+ 1.63.0
+
+
+ org.apache.tomcat
+ annotations-api
+ 6.0.53
+ provided
+
+
+
+
+ 17
+ 17
+
+
+
+
+
+ kr.motd.maven
+ os-maven-plugin
+ 1.6.2
+
+
+
+
+ org.xolstice.maven.plugins
+ protobuf-maven-plugin
+ 0.6.1
+
+ com.google.protobuf:protoc:3.9.0:exe:${os.detected.classifier}
+ grpc-java
+ io.grpc:protoc-gen-grpc-java:1.24.0:exe:${os.detected.classifier}
+
+
+
+
+ compile
+ compile-custom
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+ false
+
+
+ vslab2.src.Main
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Client/vs_lab02_grpc_log_service/src.zip b/Client/vs_lab02_grpc_log_service/src.zip
new file mode 100644
index 0000000..783ea97
Binary files /dev/null and b/Client/vs_lab02_grpc_log_service/src.zip differ
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/Main.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/Main.java
new file mode 100644
index 0000000..6ef5180
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/Main.java
@@ -0,0 +1,34 @@
+package vslab2.src;
+
+import vslab2.src.grpcStuff.GRPCInformation;
+import vslab2.src.input.ClientInformation;
+import vslab2.src.input.InputThread;
+import vslab2.src.request.RequestExecuterThread;
+import vslab2.src.request.queues.RequestQueue;
+
+public class Main {
+ public static void main(String[] args) {
+
+ RequestQueue requestQueue = new RequestQueue();
+
+ ClientInformation clientInformation = new ClientInformation();
+ GRPCInformation grpcInformation = new GRPCInformation();
+
+ RequestExecuterThread requestExecuterThread = new RequestExecuterThread(requestQueue);
+ requestExecuterThread.start();
+
+ InputThread inputThread = new InputThread(clientInformation, grpcInformation, requestQueue);
+ inputThread.start();
+
+ try {
+ inputThread.join();
+ } catch (InterruptedException e) {
+ System.err.println("Error in Main:main, inputThread was interrupted, before join.");
+ }
+ try {
+ requestExecuterThread.join();
+ } catch (InterruptedException e) {
+ System.err.println("Error in Main:main, requestExecuterThread was interrupted, before join.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/grpcStuff/GRPCInformation.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/grpcStuff/GRPCInformation.java
new file mode 100644
index 0000000..368c5bd
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/grpcStuff/GRPCInformation.java
@@ -0,0 +1,33 @@
+package vslab2.src.grpcStuff;
+
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.stub.StreamObserver;
+import vslab2.src.grpc.LogOuterClass.Log;
+import vslab2.src.grpc.LogServiceGrpc;
+import vslab2.src.response.observers.AddLogEmptyResponseObserver;
+
+public class GRPCInformation {
+ private LogServiceGrpc.LogServiceStub stub = null;
+
+ private StreamObserver addLogStreamRequestObserver = null;
+
+ public void initializeStub(String serverIP, int serverPort) {
+ ManagedChannel channel = ManagedChannelBuilder.forAddress(serverIP, serverPort)
+ .usePlaintext()
+ .build();
+ stub = LogServiceGrpc.newStub(channel);
+ }
+
+ public LogServiceGrpc.LogServiceStub getStub() {
+ return stub;
+ }
+
+ public synchronized StreamObserver getAddLogStreamObserver() {
+ return addLogStreamRequestObserver;
+ }
+
+ public synchronized void initializeAddLogStreamObserver() {
+ this.addLogStreamRequestObserver = stub.addLog(new AddLogEmptyResponseObserver());
+ }
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/ClientInformation.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/ClientInformation.java
new file mode 100644
index 0000000..b5a97eb
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/ClientInformation.java
@@ -0,0 +1,32 @@
+package vslab2.src.input;
+
+public class ClientInformation {
+ private String userId = null;
+
+ private String serverIP = null;
+ private int serverPort = 0;
+
+ public synchronized String getUserId() {
+ return userId;
+ }
+
+ public synchronized void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public synchronized String getServerIP() {
+ return serverIP;
+ }
+
+ public synchronized void setServerIP(String serverIP) {
+ this.serverIP = serverIP;
+ }
+
+ public synchronized int getServerPort() {
+ return serverPort;
+ }
+
+ public synchronized void setServerPort(int serverPort) {
+ this.serverPort = serverPort;
+ }
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/InputThread.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/InputThread.java
new file mode 100644
index 0000000..e0864dc
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/InputThread.java
@@ -0,0 +1,98 @@
+package vslab2.src.input;
+
+import java.util.Scanner;
+
+import vslab2.src.grpcStuff.GRPCInformation;
+import vslab2.src.input.commands.CommandFactory;
+import vslab2.src.input.commands.Executable;
+import vslab2.src.request.queues.RequestQueue;
+
+public class InputThread extends Thread{
+ private boolean inputThreadRunning = false;
+
+ private ClientInformation clientInformation = null;
+ private GRPCInformation grpcInformation = null;
+
+ private RequestQueue requestQueue = null;
+
+ public InputThread(ClientInformation clientInformation, GRPCInformation grpcInformation, RequestQueue requestQueue) {
+ inputThreadRunning = true;
+ this.clientInformation = clientInformation;
+ this.requestQueue = requestQueue;
+ this.grpcInformation = grpcInformation;
+ }
+
+ @Override
+ public void run() {
+
+ Scanner inputScanner = new Scanner(System.in);
+ setUserId(inputScanner);
+ setServerInformation(inputScanner);
+ grpcInformation.initializeStub(clientInformation.getServerIP(), clientInformation.getServerPort());
+
+ while (inputThreadRunning) {
+ System.out.println("-----------------------------------------------");
+ System.out.println("Enter command:");
+ String inputString = null;
+ try {
+ inputString = inputScanner.nextLine();
+ } catch (Exception e) {
+ System.err.println("Error at InputThread:run, unable to resolve command from input scanner.");
+ }
+ if ((inputString != null) && (!inputString.equals(""))) {
+ Executable command = CommandFactory.createCommandFromString(inputString, clientInformation, grpcInformation);
+ if (command != null) {
+ command.execute(requestQueue);
+ }
+ }
+ }
+ inputScanner.close();
+ }
+
+ private void setUserId(Scanner inputScanner) {
+ boolean validUserId = false;
+ while (!validUserId) {
+ System.out.println("-----------------------------------------------");
+ System.out.println("Enter user id:");
+ try {
+ clientInformation.setUserId(inputScanner.nextLine());
+ validUserId = true;
+ } catch (Exception e) {
+ System.err.println("Error: re-enter user id:");
+ }
+ }
+ }
+
+ private void setServerInformation(Scanner inputScanner) {
+ boolean validIP = false;
+ boolean validPort = false;
+
+ while (!(validIP || validPort)) {
+ System.out.println("-----------------------------------------------");
+ System.out.println("Enter IP of server:");
+ String ip = null;
+ try {
+ ip = inputScanner.nextLine();
+ validIP = true;
+ } catch (Exception e) {
+ System.err.println("Error: enter ip in format x.x.x.x");
+ validIP = false;
+ }
+
+ System.out.println("-----------------------------------------------");
+ System.out.println("Enter Port of server:");
+ int port = -1;
+ try {
+ port = Integer.valueOf(inputScanner.nextLine());
+ validPort = (port > 0);
+ } catch (Exception e) {
+ System.err.println("Error: enter number.");
+ validPort = false;
+ }
+ if (validIP && validPort) {
+ clientInformation.setServerIP(ip);
+ clientInformation.setServerPort(port);
+ }
+ }
+ }
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandAddLog.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandAddLog.java
new file mode 100644
index 0000000..5883396
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandAddLog.java
@@ -0,0 +1,37 @@
+package vslab2.src.input.commands;
+
+import vslab2.src.grpc.LogOuterClass.Log;
+import vslab2.src.grpcStuff.GRPCInformation;
+import vslab2.src.input.ClientInformation;
+import vslab2.src.request.queues.RequestQueue;
+import vslab2.src.request.requests.RequestAddLog;
+
+public class CommandAddLog implements Executable {
+
+ private String text = null;
+
+ private ClientInformation clientInformation = null;
+ private GRPCInformation grpcInformation = null;
+
+ public CommandAddLog(String text, ClientInformation clientInformation, GRPCInformation grpcInformation) {
+ this.text = text;
+ this.clientInformation = clientInformation;
+ this.grpcInformation = grpcInformation;
+ }
+
+ @Override
+ public void execute(RequestQueue requestQueue) {
+ Log log = Log.newBuilder().setUserId(clientInformation.getUserId()).setText(text).build();
+ requestQueue.add(new RequestAddLog(log, grpcInformation));
+ }
+
+ @Override
+ public ECommandType getType() {
+ return ECommandType.AddLog;
+ }
+
+ @Override
+ public int getTypeId() {
+ return getType().ordinal();
+ }
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandExit.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandExit.java
new file mode 100644
index 0000000..1d606d7
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandExit.java
@@ -0,0 +1,22 @@
+package vslab2.src.input.commands;
+
+import vslab2.src.request.queues.RequestQueue;
+
+public class CommandExit implements Executable {
+
+ @Override
+ public void execute(RequestQueue requestQueue) {
+ // TODO stopp all threads.
+ }
+
+ @Override
+ public ECommandType getType() {
+ return ECommandType.UnlistenLog;
+ }
+
+ @Override
+ public int getTypeId() {
+ return getType().ordinal();
+ }
+
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandFactory.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandFactory.java
new file mode 100644
index 0000000..9f45ec2
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandFactory.java
@@ -0,0 +1,50 @@
+package vslab2.src.input.commands;
+
+import vslab2.src.grpcStuff.GRPCInformation;
+import vslab2.src.input.ClientInformation;
+
+public class CommandFactory {
+ /**
+ * Creates command from given string which contains command name and arguments.
+ * @param commandString string which contains command and arguments.
+ * @return executable command.
+ */
+ public static Executable createCommandFromString(String commandString, ClientInformation clientInformation, GRPCInformation grpcInformation) {
+
+ String[] commandStringParts = commandString.split(" ");
+
+ String command = commandStringParts[Constants.COMMAND];
+
+ switch (command) {
+ case (Constants.ADD_LOG): {
+ return new CommandAddLog(commandStringParts[Constants.LOG_TEXT], clientInformation, grpcInformation);
+ }
+
+ case (Constants.GET_LOG): {
+ return new CommandGetLog(grpcInformation);
+ }
+
+ case (Constants.LISTEN_LOG): {
+ return new CommandListenLog(clientInformation, grpcInformation);
+ }
+
+ case (Constants.UNLISTEN_LOG): {
+ return new CommandUnlistenLog(clientInformation, grpcInformation);
+ }
+
+ case (Constants.HELP): {
+ return new CommandHelp();
+ }
+
+ case (Constants.EXIT): {
+ return new CommandExit();
+ }
+
+ default: {
+ System.err.println("Error at CommandFactory:createCommandFromString, unknown command: " + command);
+ }break;
+ }
+
+ return null;
+ }
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandGetLog.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandGetLog.java
new file mode 100644
index 0000000..b9a5000
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandGetLog.java
@@ -0,0 +1,29 @@
+package vslab2.src.input.commands;
+
+import vslab2.src.grpcStuff.GRPCInformation;
+import vslab2.src.request.queues.RequestQueue;
+import vslab2.src.request.requests.RequestGetLog;
+
+public class CommandGetLog implements Executable {
+
+ private GRPCInformation grpcInformation = null;
+
+ public CommandGetLog(GRPCInformation grpcInformation) {
+ this.grpcInformation = grpcInformation;
+ }
+
+ @Override
+ public void execute(RequestQueue requestQueue) {
+ requestQueue.add(new RequestGetLog(grpcInformation));
+ }
+
+ @Override
+ public ECommandType getType() {
+ return ECommandType.GetLog;
+ }
+
+ @Override
+ public int getTypeId() {
+ return getType().ordinal();
+ }
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandHelp.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandHelp.java
new file mode 100644
index 0000000..f73bb92
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandHelp.java
@@ -0,0 +1,28 @@
+package vslab2.src.input.commands;
+
+import vslab2.src.request.queues.RequestQueue;
+
+public class CommandHelp implements Executable {
+
+ @Override
+ public void execute(RequestQueue requestQueue) {
+ System.out.println("-----------------------------------------------");
+ System.out.println("Available commands:");
+ for (String command : Constants.COMMANDS) {
+ System.out.println(command);
+ }
+ }
+
+ @Override
+ public ECommandType getType() {
+ return ECommandType.Help;
+ }
+
+ @Override
+ public int getTypeId() {
+ return getType().ordinal();
+ }
+
+
+
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandListenLog.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandListenLog.java
new file mode 100644
index 0000000..4059b47
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandListenLog.java
@@ -0,0 +1,35 @@
+package vslab2.src.input.commands;
+
+import vslab2.src.grpc.LogOuterClass.User;
+import vslab2.src.grpcStuff.GRPCInformation;
+import vslab2.src.input.ClientInformation;
+import vslab2.src.request.queues.RequestQueue;
+import vslab2.src.request.requests.RequestListenLog;
+
+public class CommandListenLog implements Executable {
+
+ private ClientInformation clientInformation = null;
+ private GRPCInformation grpcInformation = null;
+
+ public CommandListenLog(ClientInformation clientInformation, GRPCInformation grpcInformation) {
+ this.clientInformation = clientInformation;
+ this.grpcInformation = grpcInformation;
+ }
+
+ @Override
+ public void execute(RequestQueue requestQueue) {
+ User user = User.newBuilder().setUserId(clientInformation.getUserId()).build();
+ requestQueue.add(new RequestListenLog(user, grpcInformation));
+ }
+
+ @Override
+ public ECommandType getType() {
+ return ECommandType.ListenLog;
+ }
+
+ @Override
+ public int getTypeId() {
+ return getType().ordinal();
+ }
+
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandUnlistenLog.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandUnlistenLog.java
new file mode 100644
index 0000000..de25f68
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/CommandUnlistenLog.java
@@ -0,0 +1,35 @@
+package vslab2.src.input.commands;
+
+import vslab2.src.grpc.LogOuterClass.User;
+import vslab2.src.grpcStuff.GRPCInformation;
+import vslab2.src.input.ClientInformation;
+import vslab2.src.request.queues.RequestQueue;
+import vslab2.src.request.requests.RequestUnlistenLog;
+
+public class CommandUnlistenLog implements Executable {
+
+ private ClientInformation clientInformation = null;
+ private GRPCInformation grpcInformation = null;
+
+ public CommandUnlistenLog(ClientInformation clientInformation, GRPCInformation grpcInformation) {
+ this.clientInformation = clientInformation;
+ this.grpcInformation = grpcInformation;
+ }
+
+ @Override
+ public void execute(RequestQueue requestQueue) {
+ User user = User.newBuilder().setUserId(clientInformation.getUserId()).build();
+ requestQueue.add(new RequestUnlistenLog(user, grpcInformation));
+ }
+
+ @Override
+ public ECommandType getType() {
+ return ECommandType.UnlistenLog;
+ }
+
+ @Override
+ public int getTypeId() {
+ return getType().ordinal();
+ }
+
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/Constants.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/Constants.java
new file mode 100644
index 0000000..e854d4c
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/Constants.java
@@ -0,0 +1,22 @@
+package vslab2.src.input.commands;
+
+public class Constants {
+ public static final int COMMAND = 0;
+ public static final int LOG_TEXT = 1;
+
+ public static final String ADD_LOG = "AddLog";
+ public static final String GET_LOG = "GetLog";
+ public static final String LISTEN_LOG = "ListenLog";
+ public static final String UNLISTEN_LOG = "UnlistenLog";
+ public static final String HELP = "Help";
+ public static final String EXIT = "Exit";
+
+ public static final String[] COMMANDS = {
+ "AddLog // Add entry to log",
+ "GetLog // Get whole log at once",
+ "ListenLog // Subscribe to log stream",
+ "UnlistenLog // Unsubscribe from log stream",
+ "Help // Show help",
+ "Exit // Exit application"
+ };
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/ECommandType.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/ECommandType.java
new file mode 100644
index 0000000..130fc35
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/ECommandType.java
@@ -0,0 +1,10 @@
+package vslab2.src.input.commands;
+
+public enum ECommandType {
+ AddLog,
+ GetLog,
+ ListenLog,
+ UnlistenLog,
+ Help,
+ Exit
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/Executable.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/Executable.java
new file mode 100644
index 0000000..6b6444f
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/input/commands/Executable.java
@@ -0,0 +1,10 @@
+package vslab2.src.input.commands;
+
+import vslab2.src.request.queues.RequestQueue;
+
+public interface Executable {
+ public void execute(RequestQueue requestQueue);
+ public ECommandType getType();
+ public int getTypeId();
+ public String toString();
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/RequestExecuterThread.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/RequestExecuterThread.java
new file mode 100644
index 0000000..b088088
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/RequestExecuterThread.java
@@ -0,0 +1,29 @@
+package vslab2.src.request;
+
+import vslab2.src.request.queues.RequestQueue;
+import vslab2.src.request.requests.Requestable;
+
+public class RequestExecuterThread extends Thread {
+ private boolean requestExecuterThreadRunning = false;
+
+ private RequestQueue requestQueue = null;
+
+ public RequestExecuterThread(RequestQueue requestQueue) {
+ requestExecuterThreadRunning = true;
+ this.requestQueue = requestQueue;
+ }
+
+ @Override
+ public void run() {
+ while (requestExecuterThreadRunning) {
+ if (requestQueue != null) {
+ try {
+ Requestable request = requestQueue.take();
+ request.request();
+ } catch (InterruptedException e) {
+ System.err.println("Error at RequestExecuterThread:run, request queue interrupted.");
+ }
+ }
+ }
+ }
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/queues/RequestQueue.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/queues/RequestQueue.java
new file mode 100644
index 0000000..317e48d
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/queues/RequestQueue.java
@@ -0,0 +1,10 @@
+package vslab2.src.request.queues;
+
+import java.util.concurrent.LinkedBlockingQueue;
+
+import vslab2.src.request.requests.Requestable;
+
+/**
+ * Queue containing requests that will be send over stub.
+ */
+public class RequestQueue extends LinkedBlockingQueue {}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/ERequestType.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/ERequestType.java
new file mode 100644
index 0000000..b9d3092
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/ERequestType.java
@@ -0,0 +1,8 @@
+package vslab2.src.request.requests;
+
+public enum ERequestType {
+ AddLog,
+ GetLog,
+ ListenLog,
+ UnlistenLog
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestAddLog.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestAddLog.java
new file mode 100644
index 0000000..fb09953
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestAddLog.java
@@ -0,0 +1,36 @@
+package vslab2.src.request.requests;
+
+import vslab2.src.grpc.LogOuterClass.Log;
+import vslab2.src.grpcStuff.GRPCInformation;
+
+/**
+ * AddLog request if request method is executed, will send new addLog request to server.
+ */
+public class RequestAddLog implements Requestable {
+
+ private GRPCInformation grpcInformation = null;
+ private Log log = null;
+
+ public RequestAddLog(Log log, GRPCInformation grpcInformation) {
+ this.grpcInformation = grpcInformation;
+ this.log = log;
+ }
+
+ @Override
+ public void request() {
+ if (grpcInformation.getAddLogStreamObserver() == null) {
+ grpcInformation.initializeAddLogStreamObserver();
+ }
+ grpcInformation.getAddLogStreamObserver().onNext(log);
+ }
+
+ @Override
+ public ERequestType getType() {
+ return ERequestType.AddLog;
+ }
+
+ @Override
+ public int getTypeId() {
+ return getType().ordinal();
+ }
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestGetLog.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestGetLog.java
new file mode 100644
index 0000000..6fe151d
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestGetLog.java
@@ -0,0 +1,30 @@
+package vslab2.src.request.requests;
+
+import vslab2.src.grpc.LogOuterClass.Empty;
+import vslab2.src.grpcStuff.GRPCInformation;
+import vslab2.src.response.observers.GetLogLogsResponseObserver;
+
+public class RequestGetLog implements Requestable {
+
+ private GRPCInformation grpcInformation = null;
+
+ public RequestGetLog(GRPCInformation grpcInformation) {
+ this.grpcInformation = grpcInformation;
+ }
+
+ @Override
+ public void request() {
+ grpcInformation.getStub().getLog(Empty.getDefaultInstance(), new GetLogLogsResponseObserver());;
+ }
+
+ @Override
+ public ERequestType getType() {
+ return ERequestType.GetLog;
+ }
+
+ @Override
+ public int getTypeId() {
+ return getType().ordinal();
+ }
+
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestListenLog.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestListenLog.java
new file mode 100644
index 0000000..e9b9236
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestListenLog.java
@@ -0,0 +1,32 @@
+package vslab2.src.request.requests;
+
+import vslab2.src.grpc.LogOuterClass.User;
+import vslab2.src.grpcStuff.GRPCInformation;
+import vslab2.src.response.observers.ListenLogLogStreamResponseObserver;
+
+public class RequestListenLog implements Requestable {
+
+ private User user = null;
+ private GRPCInformation grpcInformation = null;
+
+ public RequestListenLog(User user, GRPCInformation grpcInformation) {
+ this.user = user;
+ this.grpcInformation = grpcInformation;
+ }
+
+ @Override
+ public void request() {
+ grpcInformation.getStub().listenLog(user, new ListenLogLogStreamResponseObserver());
+ }
+
+ @Override
+ public ERequestType getType() {
+ return ERequestType.ListenLog;
+ }
+
+ @Override
+ public int getTypeId() {
+ return getType().ordinal();
+ }
+
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestUnlistenLog.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestUnlistenLog.java
new file mode 100644
index 0000000..42662f9
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/RequestUnlistenLog.java
@@ -0,0 +1,32 @@
+package vslab2.src.request.requests;
+
+import vslab2.src.grpc.LogOuterClass.User;
+import vslab2.src.grpcStuff.GRPCInformation;
+import vslab2.src.response.observers.UnlistenLogEmptyResponseObserver;
+
+public class RequestUnlistenLog implements Requestable {
+
+ private User user = null;
+ private GRPCInformation grpcInformation = null;
+
+ public RequestUnlistenLog(User user, GRPCInformation grpcInformation) {
+ this.user = user;
+ this.grpcInformation = grpcInformation;
+ }
+
+ @Override
+ public void request() {
+ grpcInformation.getStub().unlistenLog(user, new UnlistenLogEmptyResponseObserver());
+ }
+
+ @Override
+ public ERequestType getType() {
+ return ERequestType.UnlistenLog;
+ }
+
+ @Override
+ public int getTypeId() {
+ return getType().ordinal();
+ }
+
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/Requestable.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/Requestable.java
new file mode 100644
index 0000000..ed38b8d
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/request/requests/Requestable.java
@@ -0,0 +1,7 @@
+package vslab2.src.request.requests;
+
+public interface Requestable {
+ public void request();
+ public ERequestType getType();
+ public int getTypeId();
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/AddLogEmptyResponseObserver.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/AddLogEmptyResponseObserver.java
new file mode 100644
index 0000000..7ec2909
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/AddLogEmptyResponseObserver.java
@@ -0,0 +1,26 @@
+package vslab2.src.response.observers;
+
+import io.grpc.stub.StreamObserver;
+import vslab2.src.grpc.LogOuterClass.Empty;
+
+public class AddLogEmptyResponseObserver implements StreamObserver {
+
+ @Override
+ public void onNext(Empty value) {
+ System.out.println("-----------------------------------------------");
+ System.out.println("Log was added successfully.");
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ System.out.println("-----------------------------------------------");
+ System.out.println("Error at AddLogEmptyResponseObserver.\n" + t.toString());
+ }
+
+ @Override
+ public void onCompleted() {
+ System.out.println("-----------------------------------------------");
+ System.out.println("AddLogEmptyResponseObserver closed.");
+ }
+
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/GetLogLogsResponseObserver.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/GetLogLogsResponseObserver.java
new file mode 100644
index 0000000..19b5da6
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/GetLogLogsResponseObserver.java
@@ -0,0 +1,31 @@
+package vslab2.src.response.observers;
+
+import io.grpc.stub.StreamObserver;
+import vslab2.src.grpc.LogOuterClass.Log;
+import vslab2.src.grpc.LogOuterClass.Logs;
+
+public class GetLogLogsResponseObserver implements StreamObserver {
+
+ @Override
+ public void onNext(Logs value) {
+ System.out.println("-----------------------------------------------");
+ System.out.println("Row Number\tUser Id\tText\n");
+
+ for (Log log : value.getLogsList()) {
+ System.out.format("%010d\t%07d\t%s", log.getRowNumber(), log.getUserId(), log.getText());
+ }
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ System.out.println("-----------------------------------------------");
+ System.err.println("Error at GetLogLogsResponseObserver.\n" + t.toString());
+ }
+
+ @Override
+ public void onCompleted() {
+ System.out.println("-----------------------------------------------");
+ System.out.println("GetLogLogsResponseObserver was closed.");
+ }
+
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/ListenLogLogStreamResponseObserver.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/ListenLogLogStreamResponseObserver.java
new file mode 100644
index 0000000..be7eb09
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/ListenLogLogStreamResponseObserver.java
@@ -0,0 +1,26 @@
+package vslab2.src.response.observers;
+
+import io.grpc.stub.StreamObserver;
+import vslab2.src.grpc.LogOuterClass.Log;
+
+public class ListenLogLogStreamResponseObserver implements StreamObserver {
+
+ @Override
+ public void onNext(Log log) {
+ System.out.println("-----------------------------------------------");
+ System.out.format("%010d\t%07d\t%s", log.getRowNumber(), log.getUserId(), log.getText());
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ System.out.println("-----------------------------------------------");
+ System.err.println("Error at ListenLogLogStreamResponseObserver.\n" + t.toString());
+ }
+
+ @Override
+ public void onCompleted() {
+ System.out.println("-----------------------------------------------");
+ System.out.println("ListenLogLogStreamResponseObserver closed.");
+ }
+
+}
diff --git a/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/UnlistenLogEmptyResponseObserver.java b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/UnlistenLogEmptyResponseObserver.java
new file mode 100644
index 0000000..fddb891
--- /dev/null
+++ b/Client/vs_lab02_grpc_log_service/src/main/java/vslab2/src/response/observers/UnlistenLogEmptyResponseObserver.java
@@ -0,0 +1,26 @@
+package vslab2.src.response.observers;
+
+import io.grpc.stub.StreamObserver;
+import vslab2.src.grpc.LogOuterClass.Empty;
+
+public class UnlistenLogEmptyResponseObserver implements StreamObserver{
+
+ @Override
+ public void onNext(Empty value) {
+ System.out.println("-----------------------------------------------");
+ System.out.println("Unsubscribed from log stream.");
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ System.out.println("-----------------------------------------------");
+ System.err.println("Error at UnlistenLogEmptyResponseObserver.\n" + t.toString());
+ }
+
+ @Override
+ public void onCompleted() {
+ System.out.println("-----------------------------------------------");
+ System.out.println("UnlistenLogEmptyResponseObserver closed.");
+ }
+
+}
diff --git a/log.proto b/Client/vs_lab02_grpc_log_service/src/main/proto/log.proto
similarity index 63%
rename from log.proto
rename to Client/vs_lab02_grpc_log_service/src/main/proto/log.proto
index f1e9652..3bff730 100644
--- a/log.proto
+++ b/Client/vs_lab02_grpc_log_service/src/main/proto/log.proto
@@ -1,4 +1,5 @@
syntax = "proto3";
+package vslab2.src.grpc;
message Log {
int32 row_number = 1;
@@ -12,9 +13,13 @@ message Logs {
message Empty {}
+message User {
+ string user_id = 1;
+}
+
service LogService {
rpc AddLog(stream Log) returns (Empty);
rpc GetLog(Empty) returns (Logs);
- rpc ListenLog(Empty) returns (stream Log);
- rpc UnlistenLog(Empty) returns (Empty);
+ rpc ListenLog(User) returns (stream Log);
+ rpc UnlistenLog(User) returns (Empty);
}
\ No newline at end of file