This commit is contained in:
WickedJack99
2024-05-10 22:26:56 +02:00
parent fd2f2b2e57
commit ee2ea6cd9b
17 changed files with 384 additions and 20 deletions

View File

@@ -6,10 +6,10 @@
<groupId>vslab2.src</groupId>
<artifactId>labor2vs</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.0</version>
<dependencies>
<dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.63.0</version>
@@ -79,7 +79,10 @@
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>vslab2.src.Main</mainClass>
<mainClass>vslab2.src.Main</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/io.grpc.NameResolverProvider</resource>
</transformer>
</transformers>
</configuration>

View File

@@ -17,6 +17,8 @@ public class GRPCInformation {
.usePlaintext()
.build();
stub = LogServiceGrpc.newStub(channel);
System.out.println("-------------------------------------------------");
System.out.println("Connection to server succesful.");
}
public LogServiceGrpc.LogServiceStub getStub() {

View File

@@ -31,7 +31,7 @@ public class InputThread extends Thread{
grpcInformation.initializeStub(clientInformation.getServerIP(), clientInformation.getServerPort());
while (inputThreadRunning) {
System.out.println("-----------------------------------------------");
System.out.println("-------------------------------------------------");
System.out.println("Enter command:");
String inputString = null;
try {

View File

@@ -17,7 +17,8 @@ public class CommandFactory {
switch (command) {
case (Constants.ADD_LOG): {
return new CommandAddLog(commandStringParts[Constants.LOG_TEXT], clientInformation, grpcInformation);
String text = commandString.substring(Constants.GET_LOG.length() + 1, commandString.length());
return new CommandAddLog(text, clientInformation, grpcInformation);
}
case (Constants.GET_LOG): {

View File

@@ -13,13 +13,13 @@ public class AddLogEmptyResponseObserver implements StreamObserver<Empty> {
@Override
public void onError(Throwable t) {
System.out.println("-----------------------------------------------");
System.out.println("-------------------------------------------------");
System.out.println("Error at AddLogEmptyResponseObserver.\n" + t.toString());
}
@Override
public void onCompleted() {
System.out.println("-----------------------------------------------");
System.out.println("-------------------------------------------------");
System.out.println("AddLogEmptyResponseObserver closed.");
}

View File

@@ -8,23 +8,22 @@ public class GetLogLogsResponseObserver implements StreamObserver<Logs> {
@Override
public void onNext(Logs value) {
System.out.println("-----------------------------------------------");
System.out.println("Row Number\tUser Id\tText\n");
System.out.println("-------------------------------------------------");
System.out.println("| Row Number\t| User Id\t| Text\t\t|");
for (Log log : value.getLogsList()) {
System.out.format("%010d\t%07d\t%s", log.getRowNumber(), log.getUserId(), log.getText());
System.out.println("| " + log.getRowNumber() + "\t\t| " + log.getUserId() + "\t\t| " + log.getText() + "\t\t|");
}
}
@Override
public void onError(Throwable t) {
System.out.println("-----------------------------------------------");
System.out.println("-------------------------------------------------");
System.err.println("Error at GetLogLogsResponseObserver.\n" + t.toString());
}
@Override
public void onCompleted() {
System.out.println("-----------------------------------------------");
System.out.println("-------------------------------------------------");
System.out.println("GetLogLogsResponseObserver was closed.");
}

View File

@@ -7,19 +7,21 @@ public class ListenLogLogStreamResponseObserver implements StreamObserver<Log> {
@Override
public void onNext(Log log) {
System.out.println("-----------------------------------------------");
System.out.format("%010d\t%07d\t%s", log.getRowNumber(), log.getUserId(), log.getText());
System.out.println("-------------------------------------------------");
System.out.println("Received new log:");
System.out.println("| Row number\t| User Id\t| Text\t\t|");
System.out.println("| " + log.getRowNumber() + "\t| " + log.getUserId() + "\t| " + log.getText() + "\t\t|");
}
@Override
public void onError(Throwable t) {
System.out.println("-----------------------------------------------");
System.out.println("-------------------------------------------------");
System.err.println("Error at ListenLogLogStreamResponseObserver.\n" + t.toString());
}
@Override
public void onCompleted() {
System.out.println("-----------------------------------------------");
System.out.println("-------------------------------------------------");
System.out.println("ListenLogLogStreamResponseObserver closed.");
}

View File

@@ -7,19 +7,19 @@ public class UnlistenLogEmptyResponseObserver implements StreamObserver<Empty>{
@Override
public void onNext(Empty value) {
System.out.println("-----------------------------------------------");
System.out.println("-------------------------------------------------");
System.out.println("Unsubscribed from log stream.");
}
@Override
public void onError(Throwable t) {
System.out.println("-----------------------------------------------");
System.out.println("-------------------------------------------------");
System.err.println("Error at UnlistenLogEmptyResponseObserver.\n" + t.toString());
}
@Override
public void onCompleted() {
System.out.println("-----------------------------------------------");
System.out.println("-------------------------------------------------");
System.out.println("UnlistenLogEmptyResponseObserver closed.");
}

View File

@@ -0,0 +1,4 @@
{
"java.configuration.updateBuildConfiguration": "disabled",
"java.compile.nullAnalysis.mode": "automatic"
}

View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>vslab2.src</groupId>
<artifactId>labor2vs</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.63.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.63.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.63.0</version>
</dependency>
<dependency> <!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.9.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.24.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>vslab2.src.Main</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/io.grpc.NameResolverProvider</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,84 @@
package vslab2.src.Log;
import io.grpc.stub.StreamObserver;
import vslab2.src.User.LogUser;
import vslab2.src.User.LogUserRegistry;
import vslab2.src.grpc.LogOuterClass.Empty;
import vslab2.src.grpc.LogOuterClass.Log;
import vslab2.src.grpc.LogOuterClass.Logs;
import vslab2.src.grpc.LogOuterClass.Logs.Builder;
import vslab2.src.grpc.LogOuterClass.User;
import vslab2.src.grpc.LogServiceGrpc.LogServiceImplBase;
public class LogService extends LogServiceImplBase {
private ServerLogs logs = new ServerLogs();
private LogUserRegistry users = new LogUserRegistry();
@Override
public StreamObserver<Log> addLog(StreamObserver<Empty> responseObserver) {
return new StreamObserver<Log>() {
@Override
public void onNext(Log log) {
// Add now log to logs.
logs.addLog(new ServerLog(log.getUserId(), log.getText()));
Log logToSend = Log.newBuilder()
.setRowNumber(ServerLog.getRowNumberCounter()-1)
.setUserId(log.getUserId())
.setText(log.getText())
.build();
// Send logs to clients
for (Object subscribedUser : users.getRegisteredUsers().toArray()) {
((LogUser)subscribedUser).getStreamObserver().onNext(logToSend);
}
}
@Override
public void onError(Throwable t) {
System.err.println("Error at LogService:addLog,\n" + t.toString());
}
@Override
public void onCompleted() {
// Send Empty response to client to indicate, that stream to add messages was closed.
responseObserver.onCompleted();
}
};
}
@Override
public void getLog(Empty request, StreamObserver<Logs> responseObserver) {
Builder logsBuilder = Logs.newBuilder();
// Add logs to builder
for (ServerLog log : logs.getServerLogs()) {
logsBuilder.addLogs(
Log.newBuilder()
.setRowNumber(log.getRowNumber())
.setUserId(log.getUserID())
.setText(log.getLogText())
.build());
}
// Create response message
Logs logsResponse = logsBuilder.build();
// Send response and close response observer
responseObserver.onNext(logsResponse);
responseObserver.onCompleted();
}
@Override
public void listenLog(User request, StreamObserver<Log> responseObserver) {
// Add user to UserRegistry, which administrates all users with their response observer streams
users.registerUser(new LogUser(request.getUserId(), responseObserver));
}
@Override
public void unlistenLog(User request, StreamObserver<Empty> responseObserver) {
// Remove user from registry and close stream to client of user
StreamObserver<Log> listenedStreamObserver = users.unregisterUser(new LogUser(request.getUserId(), null));
if (listenedStreamObserver != null) {
listenedStreamObserver.onCompleted();
}
}
}

View File

@@ -0,0 +1,39 @@
package vslab2.src.Log;
public class ServerLog {
private static int rowNumberCounter = 0;
private int rowNumber = 0;
private String userID = null;
private String logText = null;
public ServerLog(String userID, String logText) {
rowNumber = rowNumberCounter++;
if (userID != null) {
this.userID = userID;
} else {
this.userID = "undefined";
}
if (logText != null) {
this.logText = logText;
} else {
this.logText = "undefined";
}
}
public static int getRowNumberCounter() {
return rowNumberCounter;
}
public int getRowNumber() {
return rowNumber;
}
public String getUserID() {
return userID;
}
public String getLogText() {
return logText;
}
}

View File

@@ -0,0 +1,22 @@
package vslab2.src.Log;
import java.util.ArrayList;
import java.util.List;
public class ServerLogs {
private List<ServerLog> logs = null;
public ServerLogs() {
logs = new ArrayList<ServerLog>();
}
public void addLog(ServerLog log) {
if (log != null) {
logs.add(log);
}
}
public List<ServerLog> getServerLogs() {
return logs;
}
}

View File

@@ -0,0 +1,27 @@
package vslab2.src;
import java.io.IOException;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import vslab2.src.Log.LogService;
public class Main {
public static void main(String[] args) {
Server server = ServerBuilder.forPort(9090).addService(new LogService()).build();
try {
server.start();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Server is online at port: " + server.getPort());
try {
server.awaitTermination();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,23 @@
package vslab2.src.User;
import io.grpc.stub.StreamObserver;
import vslab2.src.grpc.LogOuterClass.Log;
public class LogUser {
private String id = null;
private StreamObserver<Log> userResponseStreamObserver = null;
public LogUser(String id, StreamObserver<Log> observer) {
this.id = id;
this.userResponseStreamObserver = observer;
}
public boolean equals(LogUser other) {
return this.id.equals(other.id);
}
public StreamObserver<Log> getStreamObserver() {
return userResponseStreamObserver;
}
}

View File

@@ -0,0 +1,39 @@
package vslab2.src.User;
import java.util.HashSet;
import java.util.Set;
import io.grpc.stub.StreamObserver;
import vslab2.src.grpc.LogOuterClass.Log;
public class LogUserRegistry {
private Set<LogUser> users = null;
public LogUserRegistry() {
users = new HashSet<LogUser>();
}
public Set<LogUser> getRegisteredUsers() {
return users;
}
public void registerUser(LogUser user) {
if (user != null) {
users.add(user);
}
}
public StreamObserver<Log> unregisterUser(LogUser user) {
StreamObserver<Log> streamObserver = null;
if (user != null) {
for (Object logUser : users.toArray()) {
if (logUser.equals(user)) {
streamObserver = ((LogUser)logUser).getStreamObserver();
break;
}
}
users.remove(user);
}
return streamObserver;
}
}

View File

@@ -0,0 +1,25 @@
syntax = "proto3";
package vslab2.src.grpc;
message Log {
int32 row_number = 1;
string user_id = 2;
string text = 3;
}
message Logs {
repeated Log logs = 1;
}
message Empty {}
message User {
string user_id = 1;
}
service LogService {
rpc AddLog(stream Log) returns (Empty);
rpc GetLog(Empty) returns (Logs);
rpc ListenLog(User) returns (stream Log);
rpc UnlistenLog(User) returns (Empty);
}