Added writing capabilities to ObjectProcessor, completed db integration
At this moment the client is not able to receive to objects sent consecutively. This will be worked on in a future commit and should be fixed before merging this branch into develop.
This commit is contained in:
parent
597385c950
commit
26fc4374ca
5
pom.xml
5
pom.xml
@ -33,6 +33,11 @@
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>5.4.10.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.2.9</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -1,7 +1,12 @@
|
||||
package envoy.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import envoy.data.Contacts;
|
||||
import envoy.data.LoginCredentials;
|
||||
import envoy.data.User;
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
|
||||
/**
|
||||
* This {@link ObjectProcessor} handles {@link LoginCredentials}.<br>
|
||||
@ -13,7 +18,7 @@ import envoy.data.User;
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public class LoginCredentialProcessor implements ObjectProcessor<LoginCredentials, User> {
|
||||
public class LoginCredentialProcessor implements ObjectProcessor<LoginCredentials> {
|
||||
|
||||
// TODO: Acquire user IDs from database
|
||||
private static long currentUserId = 1;
|
||||
@ -22,10 +27,20 @@ public class LoginCredentialProcessor implements ObjectProcessor<LoginCredential
|
||||
public Class<LoginCredentials> getInputClass() { return LoginCredentials.class; }
|
||||
|
||||
@Override
|
||||
public User process(LoginCredentials input, long socketId) {
|
||||
public void process(LoginCredentials input, long socketId, ObjectWriteProxy writeProxy) throws IOException {
|
||||
System.out.println(String.format("Received login credentials %s from socket ID %d", input, socketId));
|
||||
|
||||
// Create user
|
||||
User user = new User(currentUserId++, input.getName());
|
||||
ConnectionManager.getInstance().registerUser(socketId, user.getId());
|
||||
return user;
|
||||
|
||||
// Create contacts
|
||||
Contacts contacts = new Contacts(user.getId(), new ArrayList<>());
|
||||
|
||||
// Complete handshake
|
||||
System.out.println("Sending user...");
|
||||
writeProxy.write(socketId, user);
|
||||
System.out.println("Sending contacts...");
|
||||
writeProxy.write(socketId, contacts);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package envoy.server;
|
||||
|
||||
import envoy.data.Message;
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
|
||||
/**
|
||||
* This {@link ObjectProcessor} handles incoming {@link Message}s.<br>
|
||||
@ -12,13 +13,13 @@ import envoy.data.Message;
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public class MessageProcessor implements ObjectProcessor<Message, Void> {
|
||||
public class MessageProcessor implements ObjectProcessor<Message> {
|
||||
|
||||
@Override
|
||||
public Class<Message> getInputClass() { return Message.class; }
|
||||
|
||||
@Override
|
||||
public Void process(Message message, long socketId) {
|
||||
public void process(Message message, long socketId, ObjectWriteProxy writeProxy) {
|
||||
|
||||
// TODO: Send message to recipient if online
|
||||
ConnectionManager connectionManager = ConnectionManager.getInstance();
|
||||
@ -27,6 +28,5 @@ public class MessageProcessor implements ObjectProcessor<Message, Void> {
|
||||
}
|
||||
|
||||
// TODO: Add message to database
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
package envoy.server;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import envoy.server.net.ObjectWriteProxy;
|
||||
|
||||
/**
|
||||
* This interface defines methods for processing objects of a specific
|
||||
* type incoming from a client.<br>
|
||||
@ -10,13 +14,12 @@ package envoy.server;
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @param <T> type of the request object
|
||||
* @param <U> type of the response object
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public interface ObjectProcessor<T, U> {
|
||||
public interface ObjectProcessor<T> {
|
||||
|
||||
/**
|
||||
* @return the Class of the request object
|
||||
* @return the class of the request object
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
Class<T> getInputClass();
|
||||
@ -27,5 +30,5 @@ public interface ObjectProcessor<T, U> {
|
||||
* @return the response object
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
U process(T input, long socketId);
|
||||
void process(T input, long socketId, ObjectWriteProxy writeProxy) throws IOException;
|
||||
}
|
@ -4,6 +4,7 @@ import java.util.Date;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
@ -28,8 +29,12 @@ import envoy.data.MessageBuilder;
|
||||
@Entity
|
||||
@Table(name = "messages")
|
||||
@NamedQueries(
|
||||
{ @NamedQuery(query = "SELECT m FROM Message m WHERE m.recipient =:recipient AND m.state = 1", name = "getUnreadMessages"), @NamedQuery(
|
||||
query = "SELECT m FROM Message m WHERE m.sender =:sender AND m.state = :state",
|
||||
{ @NamedQuery(
|
||||
query = "SELECT m FROM Message m WHERE m.recipient =:recipient AND m.status = envoy.data.Message$MessageStatus.SENT",
|
||||
name = "getUnreadMessages"
|
||||
),
|
||||
@NamedQuery(
|
||||
query = "SELECT m FROM Message m WHERE m.sender =:sender AND m.status = :status",
|
||||
name = "find read messages"//TODO do we need this namedQuery?
|
||||
), @NamedQuery(query = "SELECT m FROM Message m WHERE m.id = :messageId", name = "get message") }//TODO do we need this namedQuery?
|
||||
)
|
||||
@ -37,13 +42,22 @@ public class Message {
|
||||
|
||||
@Id
|
||||
private long id;
|
||||
private User sender, recipient;
|
||||
|
||||
@ManyToOne
|
||||
private User sender;
|
||||
|
||||
@ManyToOne
|
||||
private User recipient;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date creationDate;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date receivedDate;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date readDate;
|
||||
|
||||
private envoy.data.Message.MessageStatus status;
|
||||
private String text;
|
||||
private byte[] attachment;
|
||||
|
@ -3,6 +3,7 @@ package envoy.server.data;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
@ -27,7 +28,7 @@ import javax.persistence.TemporalType;
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
@NamedQuery(query = "SELECT u FROM DBUser u WHERE u.id = :id", name = "getUserById")
|
||||
@NamedQuery(query = "SELECT u FROM User u WHERE u.id = :id", name = "getUserById")
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@ -35,9 +36,12 @@ public class User {
|
||||
private long id;
|
||||
private String name;
|
||||
private byte[] passwordHash;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date lastSeen;
|
||||
private envoy.data.User.UserStatus status;
|
||||
|
||||
@ElementCollection
|
||||
private List<User> contacts;
|
||||
|
||||
/**
|
||||
|
@ -1,10 +1,8 @@
|
||||
package envoy.server.net;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.Set;
|
||||
|
||||
import com.jenkov.nioserver.IMessageProcessor;
|
||||
@ -25,7 +23,7 @@ import envoy.server.ObjectProcessor;
|
||||
*/
|
||||
public class ObjectMessageProcessor implements IMessageProcessor {
|
||||
|
||||
private final Set<ObjectProcessor<?, ?>> processors;
|
||||
private final Set<ObjectProcessor<?>> processors;
|
||||
|
||||
/**
|
||||
* The constructor to set the {@link ObjectProcessor}s.
|
||||
@ -33,9 +31,7 @@ public class ObjectMessageProcessor implements IMessageProcessor {
|
||||
* @param processors the {@link ObjectProcessor} to set
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public ObjectMessageProcessor(Set<ObjectProcessor<?, ?>> processors) {
|
||||
this.processors = processors;
|
||||
}
|
||||
public ObjectMessageProcessor(Set<ObjectProcessor<?>> processors) { this.processors = processors; }
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
@ -45,24 +41,16 @@ public class ObjectMessageProcessor implements IMessageProcessor {
|
||||
System.out.println("Read object: " + obj.toString());
|
||||
|
||||
// Process object
|
||||
processors.stream().filter(p -> p.getInputClass().isInstance(obj)).forEach((@SuppressWarnings("rawtypes") ObjectProcessor p) -> {
|
||||
Object responseObj = p.process(p.getInputClass().cast(obj), message.socketId);
|
||||
if (responseObj != null) {
|
||||
// Create message targeted at the client
|
||||
Message response = writeProxy.getMessage();
|
||||
response.socketId = message.socketId;
|
||||
|
||||
// Serialize object to byte array
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ObjectOutputStream oout = new ObjectOutputStream(baos)) {
|
||||
oout.writeObject(responseObj);
|
||||
processors.stream()
|
||||
.filter(p -> p.getInputClass().isInstance(obj))
|
||||
.forEach((@SuppressWarnings(
|
||||
"rawtypes"
|
||||
) ObjectProcessor p) -> {
|
||||
try {
|
||||
p.process(p.getInputClass().cast(obj), message.socketId, new ObjectWriteProxy(writeProxy));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
byte[] objBytes = baos.toByteArray();
|
||||
response.writeToMessage(objBytes);
|
||||
writeProxy.enqueue(response);
|
||||
}
|
||||
});
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
|
34
src/main/java/envoy/server/net/ObjectWriteProxy.java
Normal file
34
src/main/java/envoy/server/net/ObjectWriteProxy.java
Normal file
@ -0,0 +1,34 @@
|
||||
package envoy.server.net;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.jenkov.nioserver.Message;
|
||||
import com.jenkov.nioserver.WriteProxy;
|
||||
|
||||
import envoy.util.SerializationUtils;
|
||||
|
||||
/**
|
||||
* Project: <strong>envoy-server-standalone</strong><br>
|
||||
* File: <strong>ObjectWriteProxy.java</strong><br>
|
||||
* Created: <strong>04.01.2020</strong><br>
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Server Standalone v0.1-alpha
|
||||
*/
|
||||
public class ObjectWriteProxy {
|
||||
|
||||
private final WriteProxy writeProxy;
|
||||
|
||||
public ObjectWriteProxy(WriteProxy writeProxy) { this.writeProxy = writeProxy; }
|
||||
|
||||
public void write(long recipientSocketId, Object obj) throws IOException {
|
||||
// Create message targeted at the client
|
||||
Message response = writeProxy.getMessage();
|
||||
response.socketId = recipientSocketId;
|
||||
|
||||
// Serialize object to byte array
|
||||
byte[] objBytes = SerializationUtils.writeToByteArray(obj);
|
||||
response.writeToMessage(objBytes);
|
||||
writeProxy.enqueue(response);
|
||||
}
|
||||
}
|
29
src/main/resources/META-INF/persistence.xml
Normal file
29
src/main/resources/META-INF/persistence.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
|
||||
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
|
||||
version="2.1">
|
||||
|
||||
<persistence-unit name="envoy"
|
||||
transaction-type="RESOURCE_LOCAL">
|
||||
|
||||
<properties>
|
||||
<property name="javax.persistence.jdbc.driver"
|
||||
value="org.postgresql.Driver" /> <!-- DB Driver -->
|
||||
<property name="javax.persistence.jdbc.url"
|
||||
value="jdbc:postgresql://localhost/envoy" /> <!-- BD Mane -->
|
||||
<property name="javax.persistence.jdbc.user" value="envoy" /> <!-- DB User -->
|
||||
<property name="javax.persistence.jdbc.password"
|
||||
value="envoy" /> <!-- DB Password -->
|
||||
|
||||
<property name="hibernate.dialect"
|
||||
value="org.hibernate.dialect.PostgreSQL95Dialect" /> <!-- DB Dialect -->
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" /> <!-- create / create-drop / update -->
|
||||
|
||||
<property name="hibernate.show_sql" value="true" /> <!-- Show SQL in console -->
|
||||
<property name="hibernate.format_sql" value="true" /> <!-- Show SQL formatted -->
|
||||
</properties>
|
||||
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
Reference in New Issue
Block a user