Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
4 changes: 4 additions & 0 deletions flyway.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
flyway.url=jdbc:postgresql://185.166.39.209:5432/vlib_db
flyway.user=vlibadmin
flyway.password=T5tUb8DTh2dtMaRymzMyRKwT5kg3xqamdZJjqkLr
flyway.locations=filesystem:src/main/resources/db/migration
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/fr/host_dcode/vlib/config/WebClientConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package fr.host_dcode.vlib.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class WebClientConfig {
@Value("${velib.api.base-url}")
private String baseUrl;

@Bean
public WebClient webClient() {
return WebClient.builder()
.baseUrl(java.util.Objects.requireNonNull(baseUrl, "velib.api.base-url must not be null"))
.build();
}
}
55 changes: 29 additions & 26 deletions src/main/java/fr/host_dcode/vlib/model/Station.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package fr.host_dcode.vlib.model;


import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.*;
import org.hibernate.annotations.UpdateTimestamp;

import java.time.LocalDateTime;

Expand All @@ -13,65 +10,71 @@ public class Station {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private String id;
@Column(name = "recordid")
private String recordId;
private String name;
private String station_code;
@Column(name = "station_code")
private String stationCode;
private double latitude;
private double longitude;
private String address;
private String city;
private String description;
private LocalDateTime last_update;

@UpdateTimestamp
@Column(name = "last_update")
private LocalDateTime lastUpdate;

public Station(){}
public Station() {
}

public Station(String name, String recordId, String stationCode, double latitude, double longitude, String description) {
public Station(String name, String recordId, String stationCode, String city, double latitude, double longitude,
String description) {
this.name = name;
this.recordId = recordId;
this.station_code = stationCode;
this.stationCode = stationCode;
this.city = city;
this.latitude = latitude;
this.longitude = longitude;
this.description = description;
}

public String getStationCode(){
return this.station_code;
public String getStationCode() {
return this.stationCode;
}

public String getName(){
public String getName() {
return this.name;
}

public void setName(String name){
public void setName(String name) {
this.name = name;
}

public String getRecordId(){
public String getRecordId() {
return this.recordId;
}

public String getDescription(){
public String getDescription() {
return this.description;
}

public void setDescription(String description){
public void setDescription(String description) {
this.description = description;
}
public Double getLatitude(){

public Double getLatitude() {
return this.latitude;
}
public Double getLongitude(){

public Double getLongitude() {
return this.longitude;
}

public String getAddress(){
return this.address;
public String getCity() {
return this.city;
}

public void setAddress(String address){
this.address = address;
public void setCity(String city) {
this.city = city;
}


}
2 changes: 1 addition & 1 deletion src/main/java/fr/host_dcode/vlib/model/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public enum Status {
private String password;
@Enumerated(EnumType.STRING)
private Status status;
private LocalDateTime created_at;
private LocalDateTime createdAt;


public User(){}
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/fr/host_dcode/vlib/model/VelibApiResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package fr.host_dcode.vlib.model;

import java.util.List;

public class VelibApiResponse {

private List<VelibRecord> records;

public List<VelibRecord> getRecords() {
return records;
}

public void setRecords(List<VelibRecord> records) {
this.records = records;
}

}
42 changes: 42 additions & 0 deletions src/main/java/fr/host_dcode/vlib/model/VelibFields.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package fr.host_dcode.vlib.model;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.time.ZonedDateTime;
import java.util.List;


public class VelibFields {

@JsonProperty("recordid")
private String recordId;
private String name;
@JsonProperty("stationcode")
private String stationCode;
@JsonProperty("nom_arrondissement_communes")
private String city;
private List<Double> coordonnees_geo;
private ZonedDateTime duedate;


public String getName(){
return this.name;
}
public String getStationCode(){
return this.stationCode;
}

public String getDuedate(){
return this.duedate != null ? this.duedate.toString() : null;
}

public List<Double> getCoordonnees_geo(){
return this.coordonnees_geo;
}

public String getCity(){
return this.city;
}


}
27 changes: 27 additions & 0 deletions src/main/java/fr/host_dcode/vlib/model/VelibRecord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package fr.host_dcode.vlib.model;

import com.fasterxml.jackson.annotation.JsonProperty;

public class VelibRecord {

private VelibFields fields;
@JsonProperty("recordid")
private String recordId;

public VelibFields getFields() {
return fields;
}

public void setFields(VelibFields fields) {
this.fields = fields;
}

public String getRecordId(){
return this.recordId;
}

public void setRecordId(String recordId) {
this.recordId = recordId;
}

}
12 changes: 12 additions & 0 deletions src/main/java/fr/host_dcode/vlib/repository/StationRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package fr.host_dcode.vlib.repository;

import fr.host_dcode.vlib.model.Station;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface StationRepository extends JpaRepository<Station, String> {

Station findByStationCode(String station_code);

}
85 changes: 85 additions & 0 deletions src/main/java/fr/host_dcode/vlib/service/VelibService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package fr.host_dcode.vlib.service;

import fr.host_dcode.vlib.model.Station;
import fr.host_dcode.vlib.model.VelibApiResponse;
import fr.host_dcode.vlib.model.VelibFields;
import fr.host_dcode.vlib.repository.StationRepository;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.List;

@Service
public class VelibService {
private final WebClient webClient;
private final StationRepository stationRepository;

public VelibService(WebClient webClient, StationRepository stationRepository) {
this.webClient = webClient;
this.stationRepository = stationRepository;
}

public void fetchAndSaveVelibData() {

String queryUri = "?dataset=velib-disponibilite-en-temps-reel&rows=50";

VelibApiResponse apiResponse = webClient.get()
.uri(queryUri)
.retrieve()
.bodyToMono(VelibApiResponse.class)
.block(java.time.Duration.ofSeconds(30));

if (apiResponse == null || apiResponse.getRecords() == null || apiResponse.getRecords().isEmpty()) {
System.out.println("Aucune donnée Velib reçue.");
return;
}

apiResponse.getRecords().stream()
.map(record -> {
VelibFields fields = record.getFields();

List<Double> coords = fields.getCoordonnees_geo();
double latitude = (coords != null && coords.size() >= 1) ? coords.get(0) : 0.0;
double longitude = (coords != null && coords.size() >= 2) ? coords.get(1) : 0.0;

String description = fields.getName() + ". Dernière mise à jour: " + (fields.getDuedate() != null ? fields.getDuedate() : "inconnue");

Station station = new Station(
fields.getName(),
record.getRecordId(),
fields.getStationCode(),
fields.getCity(),
latitude,
longitude,
description
);

return station;
})
.forEach(station ->{
Station existingStation = stationRepository.findByStationCode(station.getStationCode());
if(existingStation == null){
stationRepository.save(station);
} else {
existingStation.setName(station.getName());
//ADD ALL UPDATES
stationRepository.save(existingStation);
}
});
}


@EventListener(ApplicationReadyEvent.class)
public void runAfterStartup() {
System.out.println("🚀 Démarrage de l'application détecté. Lancement de la récupération des données Velib...");

try {
fetchAndSaveVelibData();
System.out.println("✅ Récupération et sauvegarde initiales terminées.");
} catch (Exception e) {
System.err.println("❌ Erreur critique lors de la récupération initiale des données Velib : " + e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE station
ADD COLUMN recordId VARCHAR(100) NOT NULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ALTER TABLE users
ALTER COLUMN id TYPE VARCHAR(40) USING id::VARCHAR(40);


ALTER TABLE station
ALTER COLUMN id TYPE VARCHAR(40) USING id::VARCHAR(40);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE station
DROP COLUMN address;