Skip to content

Commit 1a10152

Browse files
committed
feat: implemented saving messages functionality, bug fix, state optimization and display users
1 parent 193ff97 commit 1a10152

13 files changed

Lines changed: 404 additions & 123 deletions

src/main/java/com/connect/controller/AuthController.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.connect.controller;
22

3+
import java.security.Principal;
34
import java.util.Map;
45

56
import com.connect.dto.LoginUserDTO;
67
import com.connect.dto.OtpDTO;
8+
import jakarta.servlet.http.HttpServletRequest;
79
import lombok.extern.slf4j.Slf4j;
810
import org.springframework.beans.factory.annotation.Autowired;
911
import org.springframework.http.HttpStatus;
@@ -61,4 +63,23 @@ public ResponseEntity<?> loginHandler(@RequestBody LoginUserDTO loginUser) throw
6163
var response = authService.handleLogin(loginUser);
6264
return ResponseEntity.ok(response);
6365
}
66+
67+
@GetMapping("/logout")
68+
public ResponseEntity<Map<String, String>> logoutHandler(@RequestParam("username") String username) {
69+
if (username.isEmpty()) {
70+
log.error("No user found");
71+
return ResponseEntity
72+
.status(HttpStatus.BAD_REQUEST)
73+
.body(Map.of("response", "User not found"));
74+
}
75+
if (authService.handleLogout(username) == null) {
76+
return ResponseEntity
77+
.status(HttpStatus.INTERNAL_SERVER_ERROR)
78+
.body(Map.of("response", "Something went wrong at the server"));
79+
}
80+
return ResponseEntity
81+
.status(HttpStatus.OK)
82+
.body(Map.of("response", "Logged out successfully"));
83+
84+
}
6485
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.connect.controller;
2+
3+
// Room associate handler functions are found here.
4+
5+
import com.connect.dto.RoomDTO;
6+
import com.connect.model.Room;
7+
import com.connect.service.ChatUserService;
8+
import com.connect.service.RoomService;
9+
import lombok.extern.slf4j.Slf4j;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.http.HttpStatus;
12+
import org.springframework.http.ResponseEntity;
13+
import org.springframework.messaging.handler.annotation.MessageMapping;
14+
import org.springframework.messaging.handler.annotation.Payload;
15+
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
16+
import org.springframework.messaging.simp.SimpMessagingTemplate;
17+
import org.springframework.web.bind.annotation.*;
18+
19+
import java.security.Principal;
20+
import java.util.List;
21+
import java.util.Map;
22+
import java.util.stream.Collectors;
23+
24+
@RestController
25+
@Slf4j
26+
public class ChatRoomController {
27+
28+
@Autowired
29+
private ChatUserService chatUserService;
30+
31+
@Autowired
32+
private RoomService roomService;
33+
34+
@Autowired
35+
private SimpMessagingTemplate messagingTemplate;
36+
37+
// Route for handling the joining message.
38+
@MessageMapping("/chat.join")
39+
public void joinRoom(@Payload Map<String, String> joinReq) {
40+
String username = joinReq.get("username");
41+
String roomId = joinReq.get("roomId");
42+
if (username.isEmpty() || roomId.isEmpty()) {
43+
log.error("Bad Request | Data not found");
44+
return;
45+
}
46+
chatUserService.joiningRequestHandler(username, roomId);
47+
}
48+
49+
// Handler when the user creates a new room.
50+
// Person who is creating the room must give the necessary information as in body.
51+
@PostMapping("/room/create")
52+
public ResponseEntity<String> createRoom(@RequestBody Room room, Principal principal) {
53+
// Room name is been given by the owner.
54+
// Here we derive the name of the user who is request with the help of principal.
55+
Room createdRoom = roomService.addNewRoom(room, principal);
56+
return ResponseEntity
57+
.status(HttpStatus.CREATED)
58+
.body("Room created successfully");
59+
}
60+
61+
@GetMapping("/room/getall")
62+
public ResponseEntity<List<RoomDTO>> fetchRooms() {
63+
return ResponseEntity
64+
.status(HttpStatus.OK)
65+
.body(roomService.getRooms()
66+
.stream()
67+
.map(RoomDTO::new)
68+
.collect(Collectors.toList()));
69+
}
70+
}
Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.connect.controller;
22

3-
import com.connect.dto.ChatUserDTO;
43
import com.connect.dto.MessageDTO;
4+
import com.connect.dto.UserDTO;
5+
import com.connect.model.Message;
6+
import com.connect.model.User;
57
import com.connect.service.ChatUserService;
68
import lombok.extern.slf4j.Slf4j;
79
import org.springframework.beans.factory.annotation.Autowired;
@@ -11,8 +13,9 @@
1113
import org.springframework.messaging.simp.SimpMessagingTemplate;
1214
import org.springframework.web.bind.annotation.RestController;
1315

14-
import java.util.Map;
15-
import java.util.concurrent.ConcurrentHashMap;
16+
import java.util.List;
17+
import java.util.Optional;
18+
import java.util.stream.Collectors;
1619

1720
// ChatUserController
1821
// Controller for handling the websocket routes
@@ -28,44 +31,50 @@ public class ChatUserController {
2831
@Autowired
2932
private SimpMessagingTemplate messagingTemplate;
3033

31-
// Temporary persistent (in memory) storage for saving the user.
32-
// May remove it later just for testing purpose.
33-
Map<String, ChatUserDTO> userData = new ConcurrentHashMap<>();
34-
3534
@MessageMapping("/greet")
36-
public void handleGreeting(@Payload ChatUserDTO chatUser) {
37-
log.info("Greeting Request from the user: {}", chatUser.toString());
38-
chatUserService.greetingHandler(chatUser);
35+
public void handleGreeting(SimpMessageHeaderAccessor headerAccessor) {
36+
log.info("Greeting Request from the user");
37+
String token = headerAccessor.getFirstNativeHeader("Authorization");
38+
chatUserService.greetingHandler(token);
3939
messagingTemplate.convertAndSend("/topic/greet", "websocket connection established");
4040
}
4141

42-
// Route for handling the joining message.
43-
@MessageMapping("/chat.join")
44-
public void joinRoom(SimpMessageHeaderAccessor headerAccessor) {
45-
String user = headerAccessor.getFirstNativeHeader("username");
46-
String roomID = headerAccessor.getFirstNativeHeader("roomID");
47-
log.info("Joining Request from user: {} and room: {}", user, roomID);
48-
chatUserService.joiningRequestHandler(user, roomID);
49-
}
50-
5142
@MessageMapping("/chat.send")
5243
public void handleMessage(@Payload MessageDTO message, SimpMessageHeaderAccessor headerAccessor) {
5344
// Fetching the RoomID from the header.
5445
String roomID = headerAccessor.getFirstNativeHeader("roomId");
5546
log.info("Sending the message to the room: {}", roomID);
56-
chatUserService.addMessagetoRoom(message, roomID);
57-
messagingTemplate.convertAndSend("/topic/chat/" + roomID, message);
47+
Optional<Message> dbMessage = chatUserService.addMessagetoRoom(message, roomID);
48+
dbMessage.ifPresent(msg ->
49+
messagingTemplate.convertAndSend("/topic/chat/" + roomID, msg));
5850
}
5951

6052
// Route for handling the history.
6153
@MessageMapping("/chat.history")
6254
public void handleHistory(SimpMessageHeaderAccessor headerAccessor) {
63-
String roomID = headerAccessor.getFirstNativeHeader("roomId");
64-
log.info("Handling the History of chats for the Room: {}", roomID);
65-
var messages = chatUserService.chatHistoryHandler(roomID);
66-
if (!messages.isEmpty()) {
67-
messagingTemplate.convertAndSend("/topic/history/" + roomID, messages);
68-
}
55+
String roomId = headerAccessor.getFirstNativeHeader("roomId");
56+
log.info("Handling the History of chats for the Room: {}", roomId);
57+
Optional<List<Message>> messages = chatUserService.chatHistoryHandler(roomId);
58+
messages.ifPresent(msgs -> {
59+
List<MessageDTO> dtoList = msgs.stream()
60+
.map(MessageDTO::new)
61+
.collect(Collectors.toList());
62+
63+
messagingTemplate.convertAndSend("/topic/history/"+roomId, dtoList);
64+
});
65+
}
66+
67+
@MessageMapping("/users")
68+
public void fetchUsers() {
69+
Optional<List<User>> users = chatUserService.fetchUser();
70+
users.ifPresent(users1 -> {
71+
List<UserDTO> modifiedUsers = users1
72+
.stream()
73+
.map(UserDTO::new)
74+
.collect(Collectors.toList());
75+
System.out.println("working dude");
76+
messagingTemplate.convertAndSend("/topic/users", modifiedUsers);
77+
});
6978
}
7079

7180
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
package com.connect.dto;
22

3+
import com.connect.model.Message;
34
import lombok.*;
45

6+
import java.time.LocalDateTime;
7+
58
@Data
69
@AllArgsConstructor
710
@NoArgsConstructor
811
public class MessageDTO {
912
private String sender;
1013
private String message;
14+
private LocalDateTime timeStamp;
15+
16+
public MessageDTO(Message message) {
17+
this.sender = message.getSender();
18+
this.message = message.getMessage();
19+
this.timeStamp = message.getTimeStamp();
20+
}
1121
}
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
package com.connect.dto;
22

3-
import com.connect.enums.UserRole;
43
import com.connect.enums.UserStatus;
5-
import com.connect.model.Room;
4+
import com.connect.model.User;
65
import lombok.*;
76

8-
import java.util.ArrayList;
9-
import java.util.List;
10-
117
@Data
128
@AllArgsConstructor
139
@NoArgsConstructor
14-
public class ChatUserDTO {
10+
public class UserDTO {
11+
private String id;
1512
private String username;
16-
private UserRole role;
1713
private UserStatus status;
18-
private boolean isOnline = false;
19-
private List<Room> joinedRooms = new ArrayList<>();
14+
15+
public UserDTO(User user) {
16+
this.id = user.getId().toString();
17+
this.username = user.getUsername();
18+
this.status = user.getStatus();
19+
}
2020
}
Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,41 @@
11
package com.connect.model;
22

3-
import com.connect.dto.ChatUserDTO;
4-
import com.connect.dto.MessageDTO;
53
import lombok.AllArgsConstructor;
64
import lombok.Getter;
75
import lombok.NoArgsConstructor;
86
import lombok.Setter;
7+
import org.bson.types.ObjectId;
8+
import org.springframework.data.annotation.Id;
9+
import org.springframework.data.mongodb.core.mapping.DBRef;
10+
import org.springframework.data.mongodb.core.mapping.Document;
911

10-
import java.util.ArrayList;
12+
import java.time.LocalDateTime;
1113
import java.util.List;
12-
import java.util.Map;
1314

1415
@Getter
1516
@Setter
1617
@NoArgsConstructor
1718
@AllArgsConstructor
19+
@Document(collection = "rooms")
1820
public class Room {
19-
private String roomId;
21+
@Id
22+
private ObjectId roomId;
2023
private String roomName;
21-
private Map<String, ChatUserDTO> allUsers; // The key is the username.
22-
private Map<String, ChatUserDTO> activeUsers;
23-
private List<MessageDTO> messages;
24-
}
24+
private String roomDescription;
25+
private LocalDateTime timeStamp;
26+
@DBRef
27+
private List<User> moderators;
28+
@DBRef
29+
private User admin;
30+
@DBRef
31+
private List<User> coAdmin;
32+
@DBRef
33+
private List<User> allUsers; // The key is the username.
34+
35+
public Room(String roomName, String roomDescription, User admin) {
36+
this.roomName = roomName;
37+
this.roomDescription = roomDescription;
38+
this.timeStamp = LocalDateTime.now();
39+
this.admin = admin;
40+
}
41+
}

src/main/java/com/connect/model/User.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.connect.model;
22

3+
import com.connect.enums.UserRole;
4+
import com.connect.enums.UserStatus;
35
import org.bson.types.ObjectId;
46
import org.springframework.data.annotation.Id;
57
import org.springframework.data.mongodb.core.index.Indexed;
@@ -11,6 +13,8 @@
1113
import lombok.Setter;
1214
import lombok.ToString;
1315

16+
import java.util.List;
17+
1418
@Getter
1519
@Setter
1620
@NoArgsConstructor
@@ -29,4 +33,8 @@ public class User {
2933
private String email;
3034

3135
private String password;
36+
37+
private List<UserRole> userRole;
38+
39+
private UserStatus status;
3240
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.connect.repository;
2+
3+
import com.connect.model.Message;
4+
import com.connect.model.Room;
5+
import org.bson.types.ObjectId;
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.data.mongodb.core.MongoTemplate;
8+
import org.springframework.data.mongodb.core.query.Criteria;
9+
import org.springframework.data.mongodb.core.query.Query;
10+
import org.springframework.stereotype.Repository;
11+
12+
import java.util.List;
13+
import java.util.Optional;
14+
15+
@Repository
16+
public class RoomRepository {
17+
18+
@Autowired
19+
private MongoTemplate mongoTemplate;
20+
21+
public Optional<Room> addRoom(Room room) {
22+
return Optional.of(mongoTemplate.insert(room));
23+
}
24+
25+
public Optional<List<Room>> getRooms() {
26+
Query query = new Query();
27+
query.fields()
28+
.include("roomId")
29+
.include("roomName")
30+
.include("date")
31+
.include("admin")
32+
.include("roomDescription");
33+
return Optional.of(mongoTemplate.find(query, Room.class));
34+
}
35+
36+
public Optional<Room> findRoomByID(ObjectId roomId) {
37+
Query query = new Query();
38+
query.addCriteria(Criteria.where("roomId").is(roomId));
39+
return Optional.ofNullable(mongoTemplate.findOne(query, Room.class));
40+
}
41+
42+
public Optional<Room> findRoomByName(String roomName) {
43+
Query query = new Query();
44+
query.addCriteria(Criteria.where("roomName").is(roomName));
45+
return Optional.ofNullable(mongoTemplate.findOne(query, Room.class));
46+
}
47+
48+
public Optional<Message> addMessageToRoom(Message message) {
49+
return Optional.ofNullable(mongoTemplate.insert(message));
50+
}
51+
52+
public Optional<List<Message>> getRoomSpecificMessages(ObjectId roomId) {
53+
Query query = new Query();
54+
query.addCriteria(Criteria.where("roomId").is(roomId));
55+
return Optional.of(mongoTemplate.find(query, Message.class));
56+
}
57+
58+
}

0 commit comments

Comments
 (0)