This is our Programming Project as part of the INF2 Teaching Unit supervised
by Nicolas Herbaut in Paris I Panthéon-Sorbonne University.
It contains configured CDI through Weld and Jersey's integration with HK2.
It contains persistence with JPA, implemented with Eclipse Link on top of a H2 database.
It has a REST API using JAXRS implemented by Jersey.
All the JAXB Classes are generated by an XSD with the appropriate xjc bindings
to make sure that we can handle Data smoothly.
The goal of the project is to model an application in order to respond to the problem of the Infocentre / Infogares
within the SNCF train company, we implemented business logic corresponding to given specifications, and made the components communicate as required.
This section details our conception choices.
project-jee8
is the parent project.
This project contains JAXB generated DTO to be used for communication in the REST, JMS and Business Layer. a.k.a. between the Trains and the Infocentre, and between the Infocentre and the Infogares.
DTOs :
-
LiveInfo
: Is used by the train to transmit live information to the Infocenter.
Containing :lastGareIndex
: Sequential index of the last station traveled by the train.nextGareIndex
: Sequential index of the station where the train is going.percentage
: Percentage of distance traveled between stationslastGareIndex
andnextGareIndex
.timestamp
: Time and date the LiveInfo is sent.
-
InfoDTO
: Is used by the Infocenter to transmit train informations to Infogares according to their JMS topic subscriptions. Containing :infoType
: Type of the information sent by the Infocenter (seeInfoTypeEnum
).trainId
: ID of the train concerned by the DTO.trainName
: Name of the train concerned by the DTO.trainType
: Type of the train concerned by the DTO.timestamp
: Time the train arrives at this station.- In case of disruption, the field
disruptionType
is also filled (seeEnumConditions
).
Enums :
-
InfoTypeEnum
: Contains different types ofInfoDTO
(Departure
,Arrival
,Transit
,Disruption
), used to determine the type of information received by the Infogare. TheAll
field is used to tell the Infogare to display all types of information. -
EnumConditions
: Contains different types of train delay reasons, used in a scenario where a train is delayed because of certain circumstances.
This project contains a REST API (JAXRS), the persistence layer (JPA), the service layer and makes use of Messaging Topics (JMS) to send information
REST API made with Jersey (reference implementation of JAX-RS), contains two REST controllers :
-
TrainEndpoint
: This is the main endpoint of the application, the train must make a POST request to/{id}/live
to send itsLiveInfo
(in request body) or to/{id}/live
to send info with a delay cause. -
DatabaseEndpoint
: Has no value in business logic, only used in this project to populate the database with test data by calling/db/populate
and to send first information to infogares by calling/db/init
.
Contains classes that handle business logic by performing the necessary calculations and dealing with the persistence layer. See JavaDoc for information about their methods.
-
TrainService
: First service called when receivingLiveInfo
. Contains a method that calculates the delay based on the received information. Calls the other services according to the delay. -
StopService
: Contains the implementation of :Un train desservira exceptionnellement une gare si elle est sur son trajet et que le train précédent a un retard de plus de 2h.
-
TERService
: Contains the implementation of :Un TER pourra attendre un TGV, mais pas l’inverse.
-
RuptureService
: Contains the implementation of :On ne retardera le train que si le nombre de passagers ayant réservés en rupture de correspondance est > 50.
Note : If trains A, B and C are delayed and cause more than 50 connection breaks (Ruptures) on a train D in a station G, the train D will be delayed to the arrival time of the latest train which arrives at G.
-
InfogareSenderService
: Is responsible of sending theInfoDTO
to the Infogares, uses the right JMS Publisher according to thegareId
field. JMSPublishers are classes which handle the JAXB Marshalling of the DTO and send it to the topic injected in them.See JavaDoc and code comments for more details about services.
Use of JPA with an H2 in-memory database, and the DAO pattern as an interface to isolate the business and the
persistence layers.
Contains tables :
Trajet
: Describes a ride, with a name, type, lists of passengers and stations.parcoursId
: If two train have the sameparcoursId
, they have exactly the same route but not necessarily the same service.
Passager
: Describes a passenger, used to determine any train connection breaks.Correspondance
: Describes the reservation of a passenger for another train.
Notable fields :rupture
: Boolean used to mark a connection as broken. Helps in business rule 3.
DesserteTheorique
: Describes the scheduled service of the train. Used in business logic to compare with the current one.DesserteReelle
: Describes the actual service of the train, after the delays and the decisions of the Infocenter.
Notable fields :seq
: The sequential number of the station, used in theLiveInfo
DTO.desservi
: A boolean, tells if the station is served by the train.
Gare
: Describes a station.
Notable fields :code
: Used in JMS messaging to determine the topic associated to the station.
Use of the Publish-Subscribe mechanism with one topic per station, and injection with CDI, the suppliers provide the necessary instances to be injected.
This project consumes InfoDTO
produced by the Infocenter. Has a TrainSubscriber which is responsible of
Unmarshalling the DTO, filtering and printing it as a formatted output.
The JMSProducer provides the topic instance to be injected into the subscriber.
The data is kept in a HashMap (Map<Integer, InfoDTO>
) of key trainId
, which ensures us that we have
only one information about a given train at a time.
Preview : (looks much better in IntelliJ <3)
This project is supposed to call Infogare REST API using Jersey Client for JAXRS. But we gave the teacher a Postman collection for him to test our project.
BDX = "Bordeaux Saint-Jean"; PAR = "Paris Montparnasse"; AMS = "Gare d'Amiens"; LIL = "Lille Flandres"; LYN = "Lyon Perrache".
mvn clean install
in root- Run
Main.main()
inproject-jee8-webapp
- Run
InfoGareApp.main()
inproject-jee8-jms-subscriber
five times, each time by uncommenting one topic injection injms/TrainSubscriber
(starting from line 27), you can also choose which information to display by changing the value ofinfoGareType
inTrainSubscriber
. - Import
files/postman.json
in Postman - Run requests in this order :
1 - PopulateDB
to populate database with the modeled scenario data.2 - Init
to send first data to the Infogares, you can now check train states in thejms-subscriber
consoles.3 - LiveInfo
to send live info, you can now check the changes in the Infogare screens.
We used Project Lombok in this project to help us reduce boilerplate code like getters, setters etc.
Make sure you enable Annotation Processing, and that you have it in your compile classpath on Eclipse or have installed the
Lombok IntelliJ Plugin.
Baeldung : Setting up Lombok with Eclipse and IntelliJ
These are a few SQL statements to paste in the H2 database to have a better visibility on what happens.
- View the current route of a train (replace
TRAJET_ID
value)
SELECT DESSERTEREELLE.*, NOM AS NOM_GARE, TYPE
FROM DESSERTEREELLE, GARE, TRAJET
WHERE TRAJET_ID=1
AND DESSERTEREELLE.GARE_ID=GARE.ID
AND DESSERTEREELLE.TRAJET_ID=TRAJET.ID
ORDER BY SEQ
- View Correspondance states
SELECT GARE.NOM AS NOM_GARE, PASSAGER_ID, PASSAGER.TRAJET_ID, RUPTURE, NEWDATE
FROM CORRESPONDANCE, TRAJET, PASSAGER, GARE
WHERE CORRESPONDANCE.TRAJET_ID=TRAJET.ID
AND PASSAGER.CORRESPONDANCE_ID=CORRESPONDANCE.ID
AND CORRESPONDANCE.GARE_ID=GARE.ID
Business logic code (Service Layer) is 80% covered by unit tests.
CI with Bitbucket pipelines
M1 MIAGE APP
Université Paris I Panthéon Sorbonne
Repository link : https://bitbucket.org/maxtag/sncf-infogare