Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Group Service #32

Merged
merged 37 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
4a1ed4e
module setup
pelazas Feb 24, 2024
d0171ef
small fix
pelazas Feb 24, 2024
06554a7
make container work
pelazas Feb 24, 2024
98844b1
Group Entity Fields
Miguel-Estape-Fernandez Feb 26, 2024
aeb2e30
Definir endpoints
Miguel-Estape-Fernandez Feb 26, 2024
1654ef9
add comments to structure development
pelazas Feb 27, 2024
85de81a
Group fields added
Miguel-Estape-Fernandez Mar 3, 2024
4b5038a
Group "/create" petition added
Miguel-Estape-Fernandez Mar 3, 2024
959511c
Find group and find user added
Miguel-Estape-Fernandez Mar 4, 2024
753f161
Group service "/join" petition added
Miguel-Estape-Fernandez Mar 4, 2024
c16ad86
Group service "/leave" petition added
Miguel-Estape-Fernandez Mar 4, 2024
3d4c9e8
Group service "/kickUser" petition added
Miguel-Estape-Fernandez Mar 4, 2024
3a5d778
Changes every where
Miguel-Estape-Fernandez Mar 4, 2024
1b4186b
Group Service test
Miguel-Estape-Fernandez Mar 4, 2024
ec8f7a6
One to Many realtion between User and Group added
Miguel-Estape-Fernandez Mar 5, 2024
d3d27d9
Modules not been found problems fixed
Miguel-Estape-Fernandez Mar 10, 2024
dd4a8c2
Create Group FIXED and better test for group service
Miguel-Estape-Fernandez Mar 11, 2024
36eaf08
Group service /join fixed and changes to error handling of getGroupBy…
Miguel-Estape-Fernandez Mar 11, 2024
1d2212a
All test passing /leave fixed
Miguel-Estape-Fernandez Mar 11, 2024
06d0bd4
/kickUser petition fixed
Miguel-Estape-Fernandez Mar 11, 2024
8935ddd
merge with dev
pelazas Mar 13, 2024
ce77016
create docker image ghcr.io
pelazas Mar 13, 2024
a16b830
[WIP] refactoring
pelazas Mar 13, 2024
a32b652
finish refactoring
pelazas Mar 13, 2024
9f749f7
finish refactoring group service + postman
pelazas Mar 13, 2024
267aaf4
postman requests
pelazas Mar 13, 2024
134173a
tests for join group
pelazas Mar 13, 2024
5c0edbe
tests for leaving the group
pelazas Mar 13, 2024
3d760c5
test for /createGroup
pelazas Mar 13, 2024
a97a195
get group by id
pelazas Mar 13, 2024
cf7899b
add group to user
pelazas Mar 13, 2024
55f1e7a
create group gateway
pelazas Mar 13, 2024
1a85903
exit current group on create new group
pelazas Mar 13, 2024
f4e6aa6
leave group gateway
pelazas Mar 13, 2024
1f59e4d
get group by id
pelazas Mar 13, 2024
041a71d
leave group gateway
pelazas Mar 13, 2024
b762889
gateway service postman
pelazas Mar 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ services:
environment:
MONGODB_URI: mongodb://mongodb:27017/userdb

groupservice:
container_name: groupservice-${teamname:-defaultASW}
image: ghcr.io/arquisoft/wiq_en2a/groupservice:latest
profiles: ["dev", "prod"]
build: ./game/groupservice
depends_on:
- mongodb
ports:
- "8005:8005"
networks:
- mynetwork
environment:
MONGODB_URI: mongodb://mongodb:27017/userdb

gatewayservice:
container_name: gatewayservice-${teamname:-defaultASW}
image: ghcr.io/arquisoft/wiq_en2a/gatewayservice:latest
Expand All @@ -78,6 +92,7 @@ services:
- authservice
- questiongeneratorservice
- gameservice
- groupservice
ports:
- "8000:8000"
networks:
Expand All @@ -87,6 +102,7 @@ services:
USER_SERVICE_URL: http://userservice:8001
QG_SERVICE_URL: http://questiongeneratorservice:8003
GAME_SERVICE_URL: http://gameservice:8004
GROUP_SERVICE_URL: http://groupservice:8005

webapp:
container_name: webapp-${teamname:-defaultASW}
Expand Down
2 changes: 2 additions & 0 deletions game/groupservice/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
coverage
20 changes: 20 additions & 0 deletions game/groupservice/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Use an official Node.js runtime as a parent image
FROM node:20

# Set the working directory in the container
WORKDIR /usr/src/groupservice

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install app dependencies
RUN npm install

# Copy the app source code to the working directory
COPY . .

# Expose the port the app runs on
EXPOSE 8005

# Define the command to run your app
CMD ["node", "group-service.js"]
158 changes: 158 additions & 0 deletions game/groupservice/GroupController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
const uuid = require('uuid');
const generateJoinCode = require('./util/GenerateJoinCode');
const Group = require('./group-model');

const maxNumUsers = 30;

let GroupController = {
joinGroup: async (req,res) => {
try{
requiredFields = ['uuid','groupName']
validateRequiredFields(req, requiredFields);
const group = await getGroupByName(req.body.groupName);

if(group.members.includes(req.body.uuid)){
res.json({ message: 'User is already in this group' });
return;
}

if(group.members.length == maxNumUsers){
res.json({ message: 'This group is full' });
return;
}

if(!group.isPublic){
if(group.joinCode != req.body.joinCode){
res.json({ message: 'Invalid join code' });
return;
}
}

group.members.push(req.body.uuid);

const response = await group.save()

res.json(response);

}catch(error){
console.log(error)
res.status(400).json({error: error.message})
}

},
leaveGroup: async (req,res) => {
try{
console.log(req.body)
requiredFields = ['expelledUUID','groupName', 'adminUUID']
validateRequiredFields(req, requiredFields);
const group = await getGroupByName(req.body.groupName);
console.log(req.body.adminUUID +" - "+ req.body.expelledUUID)
if(req.body.adminUUID != group.admin && req.body.adminUUID != req.body.expelledUUID){
console.log("entra en la condicion")
res.json({ message: 'User is unable to perform this operation' });
return;
}

group.members = group.members.filter(member => member != req.body.expelledUUID)

if(group.members.length == 0){
await group.deleteOne()
res.json({ message: 'Group deleted' });
return;
}

if(group.admin == req.body.expelledUUID){
group.admin = group.members.at(0);
}

const response = await group.save()
res.json(response);

}catch(error){
console.log(error)
res.status(500).json({error: error.message})
}
},
createGroup: async (req,res) =>{
try{

requiredFields =['groupName','creatorUUID','description','isPublic']
validateRequiredFields(req,requiredFields);

let newGroup;
if(req.body.isPublic){

newGroup = new Group({
admin: req.body.creatorUUID,
members: [req.body.creatorUUID],
maxNumUsers: maxNumUsers,
description: req.body.description,
isPublic: true,
creationDate: Date(),
groupName: req.body.groupName,
uuid: uuid.v4(),
})
await newGroup.save();

} else {
const joinCode = generateJoinCode();

newGroup = new Group({
groupName: req.body.groupName,
admin: req.body.creatorUUID,
members: [req.body.creatorUUID],
maxNumUsers: maxNumUsers,
description: req.body.description,
isPublic: false,
joinCode: joinCode,
creationDate: Date(),
uuid: uuid.v4(),
});
await newGroup.save();
}
res.json(newGroup);

} catch(error){
res.status(500).json({error: error.message})
}

},
getGroup: async (req, res) => {
try{
const uuid = req.params.uuid
const group = await Group.findOne({uuid: uuid})
if(!group){
res.status(404).json({error: 'Group not found'})
return;
}
res.json(group)
} catch(error){
res.status(500).json({error: error.message})
}
}
}

async function getGroupByName(name) {
try {
const group = await Group.findOne({ groupName: name });

if (!group) {
throw new Error('This group does not exist');
}

return group;
} catch (error) {
// Handle the error here
throw new Error(error.message);
}
}

function validateRequiredFields(req, requiredFields) {
for (const field of requiredFields) {
if (!(field in req.body)) {
throw new Error(`Missing required field: ${field}`);
}
}
}

module.exports = GroupController;
45 changes: 45 additions & 0 deletions game/groupservice/group-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const mongoose = require('mongoose');

const groupSchema = new mongoose.Schema({
uuid: {
type: String,
required: true,
},
groupName: {
type: String,
required: true,
unique: true,
},
admin: {
type: String,
required: true,
},
members:[{
type: String,
required: true,
}],
maxNumUsers: {
type: Number,
required: true,
},
description: {
type: String,
required: false,
},
isPublic: {
type: Boolean,
required: true,
},
joinCode: {
type: String,
required: false,
},
creationDate: {
type: Date,
default: Date.now,
}
});

const Group = mongoose.model('Group', groupSchema);

module.exports = Group;
32 changes: 32 additions & 0 deletions game/groupservice/group-service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const express = require('express');
const mongoose = require('mongoose');
const GroupController = require('./GroupController');

const app = express();
const port = 8005;

app.use(express.json());

// Connect to MongoDB
const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/userdb';
mongoose.connect(mongoUri);

app.get('/', (req, res) => {
res.json({ message: 'Welcome to group service module' });
});

app.post('/joinGroup', GroupController.joinGroup);
app.post('/leaveGroup', GroupController.leaveGroup);
app.post('/createGroup', GroupController.createGroup);
app.get('/getGroup/:uuid', GroupController.getGroup);

const server = app.listen(port, () => {
console.log(`Group Service listening at http://localhost:${port}`);
});

server.on('close', () => {
// Close the Mongoose connection
mongoose.connection.close();
});

module.exports = server
Loading
Loading