Commit c3934677 authored by Allan COMISSO's avatar Allan COMISSO

[FIX] Fix conflicts updating from initial repo

parents ebad8722 e451f8f6
......@@ -30,3 +30,37 @@ Vous n’êtes pas seul...
The current source code organization is based on the following article:
https://frakton.com/utilizing-maven-front-end-plugin-for-angular-spring-boot/
== Livrables attendus
=== Analyse du domaine
Objectif::
Description du jeu _Not Alone_ sous la forme d'un diagramme de classes conceptuelles et d'actions
Moyens::
Utilisez une approche itérative pour découvrir toutes les classes conceptuelles et les actions du jeu.
=== Conception préliminaire
Objectif::
Découpage de la solution en composants (ou sous-systèmes) et spécification des interfaces fournies et requises par ces composants
Moyens::
Utilisez des diagrammes d'interaction (séquence, communication) pour décrire l'échange de messages entre les composants pour en déduire leurs interfaces.
=== Conception détaillé
Objectif::
Spécification détaillée des composants: leur structure (diagramme de classes de conception), ainsi que le comportement de chaque opération fournie par le composants. Le comportement peut-être décrit en utilisant les diagrammes d'activité, d'interaction, les machines d'état, ainsi que OCL.
Moyens::
Appliquez les concepts vus en cours: design patterns, principes GRASP, bonnes pratiques, etc.
=== Code source
Objectif::
Code de mise en oeuvre et tests de l'application.
Moyens::
Appliquez les enseignements de l'UE "Construction et évolution de logiciels" pour produire un code source de qualité.
\ No newline at end of file
package com.example.calculator;
import com.example.calculator.handler.CalculatorServiceHandler;
import org.apache.thrift.procotol.*;
import org.apache.thrift.servicer.TServlet;
import org.springframework.boot.StringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.*;
import javax.servlet.Servlet;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class CalculatorApplication {
public static void main(String[] args) {
StringApplication.run(CalculatorApplication.class, args);
}
@Bean
public TProtocolfactory tProtocolFactory() {
return new TBinaryProtocol.Factory();
}
@Bean
public Servlet calculator(TProtocolFactory protocolFactory, CalculatorService handler) {
return new TServlet(new TCalculatorService.Processor< CalculatorServiceHandler> (handler), protocolFactory)
}
}
\ No newline at end of file
namespace java fr.univnantes.alma.core
namespace java fr.univnantes.alma.thrift
namespace js core
exception InvalidOperationException {
1: i32 code,
2: string description
}
exception GameNotFound {
1: i32 code,
2: string description
}
include "common.thrift"
namespace java fr.univnantes.alma.thrift
service GameClientService {
bool ping() throws (1:common.InvalidOperationException e)
}
include "common.thrift"
struct CrossPlatformResource {
1: i32 id,
2: string name,
3: optional string salutation
namespace java fr.univnantes.alma.thrift
struct JoinRequest {
1: string name
}
service GameServerService {
CrossPlatformResource get(1:i32 id) throws (1:common.InvalidOperationException e),
void save(1:CrossPlatformResource resource) throws (1:common.InvalidOperationException e),
list <CrossPlatformResource> getList() throws (1:common.InvalidOperationException e),
i32 createGame(i32 numberOfPlayers)
bool ping() throws (1:common.InvalidOperationException e)
i32 join(i32 gameId, JoinRequest request) throws (1:common.GameNotFound e)
}
= Conception détaillée
== Game Server
.GameSever
[plantuml]
....
interface GameServer {
createGame(numberOfPlayers : Integer): Integer
join(gameId : Integer): Integer
}
package game {
class "GameServerController" as controller {
createGame(numberOfPlayers : Integer): Integer
join(gameId : Integer): Integer
}
class "Game \n[Thread]" as game {
id : Integer {id}
numberOfPlayers : Integer
}
class "Player" as player {
id : Integer {id}
}
GameServer <|-- controller
controller *- "[*] games" game : \t\t\t
game *-- "[0..7] players" player
}
note right of game: Uncompleted!
....
[plantuml]
....
state Game {
[*] --> Created
Created -> Started : start()
Started -> Phase1 : \t
Phase1 --> [*]
}
note right of Game : Uncompleted!
....
=== Opérations du GameServerController
.Create Game
[source,OCL]
----
GameServerController::createGame(numberOfPlayers : Integer): Integer
pre:
numberOfPlayers > 1 and numberOfPlayers <= 7
post:
self.games -> exists(each | each.isOclNew())and
game.oclinState(Created)
----
.Join Game
[source,OCL]
----
GameServerController::join(gameId : Integer): Integer
pre:
self.games -> exists(each | each.id = gameId)
post:
let game = self.games->select(id = gameId)->first() in
game.players->exists(each| each.isOclNew())
----
.Start Game
[plantuml]
----
partition Game::run() {
start
while (enough players?)
:JoinRequest<
:handleRequest();
endwhile
:Game Start>
stop
}
----
......@@ -6,8 +6,8 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath></relativePath>
<version>2.4.0</version>
<relativePath/>
</parent>
<groupId>fr.univnantes.alma</groupId>
......@@ -16,26 +16,33 @@
<name>Not Alone Server</name>
<description>Spring Boot Not Alone server</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>fr.univnantes.alma</groupId>
<artifactId>not-alone-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.atlanmod.commons</groupId>
<artifactId>commons-core</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
......
package fr.univnantes.alma;
import fr.univnantes.alma.thrift.GameServerService;
import fr.univnantes.alma.handler.GameServiceHandler;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.server.TServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
import javax.servlet.Servlet;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class NotAloneApplication {
public static void main(String[] args) {
SpringApplication.run(NotAloneApplication.class, args);
}
@Bean
public TProtocolFactory tProtocolFactory() {
return new TBinaryProtocol.Factory();
}
@Bean
public ServletRegistrationBean gameServer(TProtocolFactory protocolFactory, GameServiceHandler handler) {
TServlet tServlet = new TServlet(new GameServerService.Processor<>(handler), protocolFactory);
return new ServletRegistrationBean(tServlet, "/api");
}
}
package fr.univnantes.alma.common;
public class GameJoinRequest {
}
package fr.univnantes.alma.common;
import fr.univnantes.alma.common.GameJoinRequest;
public interface GameService {
/**
* Creates a game for a number of players
* @param expectedPlayers The number of expected players, between 2 and 7
*
* @return an int, the game identification
*/
int createGame(int expectedPlayers);
/**
*
* @param gameId
* @param request
* @return
*/
int join(int gameId, GameJoinRequest request);
}
package fr.univnantes.alma.game;
import fr.univnantes.alma.common.GameJoinRequest;
import org.atlanmod.commons.log.Log;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
public class Game {
/**
* Stores arriving registrations.
*/
private final BlockingQueue<GameJoinRequest> requests;
/**
* Counter used to increment player identifications.
*/
private final AtomicInteger idCounter = new AtomicInteger(0);
private final AtomicInteger expectedPlayers;
private Thread play;
public Game(int expectedPlayers) {
this.expectedPlayers = new AtomicInteger(expectedPlayers);
this.requests = new ArrayBlockingQueue<>(expectedPlayers);
play = new Thread(() -> this.start());
play.start();
}
public int join(GameJoinRequest request) {
int id = idCounter.getAndIncrement();
requests.offer(request);
return id;
}
private void start() {
this.waitForPlayers();
Log.info("We can start !");
}
private void waitForPlayers() {
Log.info("Waiting for request. Expecting {0} players.", expectedPlayers);
GameJoinRequest request;
while (requests.size() < expectedPlayers.intValue()) {
try {
request = requests.take();
this.handleRequest(request);
} catch (InterruptedException e) {
Log.error(e);
}
}
}
private void handleRequest(GameJoinRequest request) {
}
}
package fr.univnantes.alma.game;
import fr.univnantes.alma.common.GameJoinRequest;
import fr.univnantes.alma.common.GameService;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import static org.atlanmod.commons.Preconditions.checkArgument;
@Component
public class GameServiceController implements GameService {
private final AtomicInteger idCounter = new AtomicInteger(0);
private final Map<Integer, Game> games = new HashMap<>();
@Override
public int createGame(int expectedPlayers) {
checkArgument(expectedPlayers > 1 && expectedPlayers <= 7, "A game must have between 2 and 7 players");
int newId = idCounter.incrementAndGet();
Game newGame = new Game(expectedPlayers);
games.put(newId, newGame);
return newId;
}
@Override
public int join(int gameId, GameJoinRequest request) {
Game game = games.get(gameId);
return game.join(request);
}
}
package fr.univnantes.alma.handler;
import fr.univnantes.alma.common.GameJoinRequest;
import fr.univnantes.alma.thrift.GameNotFound;
import fr.univnantes.alma.thrift.GameServerService;
import fr.univnantes.alma.thrift.JoinRequest;
import fr.univnantes.alma.common.GameService;
import org.apache.thrift.TException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class GameServiceHandler implements GameServerService.Iface {
@Autowired
GameService service;
@Override
public int createGame(int numberOfPlayers) throws TException {
return service.createGame(numberOfPlayers);
}
@Override
public int join(int gameId, JoinRequest request) throws TException {
//TODO: translate JoinRequest into GameJoinRequest
return service.join(gameId, new GameJoinRequest());
}
}
package fr.univnantes.alma;
import fr.univnantes.alma.thrift.GameServerService;
import fr.univnantes.alma.thrift.JoinRequest;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.THttpClient;
import org.apache.thrift.transport.TTransport;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = NotAloneApplication.class)
class NotAloneApplicationTest {
@Autowired
protected TProtocolFactory protocolFactory;
@LocalServerPort
protected int port;
protected GameServerService.Iface client;
@BeforeEach
public void setUp() throws Exception {
TTransport transport = new THttpClient("http://localhost:" + port + "/api");
TProtocol protocol = protocolFactory.getProtocol(transport);
client = new GameServerService.Client(protocol);
}
@Test
public void testCreateGame() throws TException {
int id = client.createGame(4);
assertThat(id).isGreaterThan(0);
}
@Test
public void testJoinGame() throws TException, InterruptedException {
int id = client.createGame(4);
client.join(id, new JoinRequest("one"));
client.join(id, new JoinRequest("two"));
client.join(id, new JoinRequest("three"));
client.join(id, new JoinRequest("four"));
Thread.sleep(1000);
}
}
......@@ -21,7 +21,7 @@
<configuration>
<workingDirectory>./</workingDirectory>
<nodeVersion>v14.11.0</nodeVersion>
<npmVersion>6.14.8</npmVersion>
<npmVersion>7.0.10</npmVersion>
</configuration>
<executions>
<execution>
......@@ -29,12 +29,17 @@
<goals>
<goal>install-node-and-npm</goal>
</goals>
<phase>generate-resources</phase>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
<phase>generate-resources</phase>
</execution>
<execution>
<id>npm run build</id>
......@@ -46,8 +51,8 @@
</configuration>
</execution>
<execution>
<id>code geneation</id>
<phase>generate-sources</phase>
<id>code generation</id>
<phase>compile</phase>
<goals>
<goal>npm</goal>
</goals>
......
......@@ -12,8 +12,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.9</maven.compiler.source>
<maven.compiler.target>1.9</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<commons.version>1.0.5</commons.version>
</properties>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment