refactor: database connection and add Store class

pull/5/head
Frédérik Benoist 2023-11-18 09:08:44 +01:00
parent 2c0b705ab6
commit 8256f2c8a6
16 changed files with 533 additions and 110 deletions

24
pom.xml
View File

@ -44,7 +44,7 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version> <!-- Remplacez par la version appropriée -->
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
@ -52,9 +52,29 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version> <!-- Utilisez la dernière version disponible -->
<version>2.13.0</version>
</dependency>
<!-- LOG dependencies -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.11</version>
</dependency>
<!-- LOG dependencies -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>
<!-- LOG dependencies -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,62 @@
package com.example.services;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DatabaseConnectDOTSOFT implements AutoCloseable {
private static final Logger logger = LoggerFactory.getLogger(DatabaseConnectDOTSOFT.class);
private Connection connection;
public DatabaseConnectDOTSOFT(String username) throws SQLException {
String environment = loadEnvironment();
Properties dbProperties = loadDatabaseProperties();
String url = dbProperties.getProperty(environment + ".db.url");
String userpassword = dbProperties.getProperty(environment + ".db." + username + ".password");
connection = DriverManager.getConnection(url, username, userpassword);
logger.info("DOTSOFT Connection OK for user " + username + " on environment " + environment);
}
public Connection getConnection() {
return connection;
}
@Override
public void close() throws SQLException {
if (connection != null && !connection.isClosed()) {
connection.close();
logger.info("DOTSOFT Connection closed");
}
}
private String loadEnvironment() {
Properties envProperties = loadProperties("env.properties");
return envProperties.getProperty("environment");
}
private Properties loadDatabaseProperties() {
Properties dbProperties = loadProperties("db.properties");
return dbProperties;
}
private Properties loadProperties(String fileName) {
Properties properties = new Properties();
try (InputStream input = getClass().getClassLoader().getResourceAsStream(fileName)) {
properties.load(input);
} catch (IOException e) {
e.printStackTrace();
// Handle the exception correctly for your application
}
return properties;
}
}

View File

@ -0,0 +1,57 @@
package com.example.services;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DatabaseConnectXSTORE implements AutoCloseable {
private static final Logger logger = LoggerFactory.getLogger(DatabaseConnectXSTORE.class);
private Connection connection;
public DatabaseConnectXSTORE(String dbHost, String username) throws SQLException {
Properties dbProperties = loadDatabaseProperties();
String url = dbProperties.getProperty("xstore.db.url").replace("HOST", dbHost);
String userpassword = dbProperties.getProperty("xstore.db." + username + ".password");
// Initialiser votre connexion à la base de données ici
connection = DriverManager.getConnection(url, username, userpassword);
logger.info("XSTORE Connection OK for user " + username + " on host " + dbHost);
}
public Connection getConnection() {
return connection;
}
@Override
public void close() throws SQLException {
if (connection != null && !connection.isClosed()) {
connection.close();
logger.info("XSTORE Connection closed");
}
}
private Properties loadDatabaseProperties() {
Properties dbProperties = loadProperties("db.properties");
return dbProperties;
}
private Properties loadProperties(String fileName) {
Properties properties = new Properties();
try (InputStream input = getClass().getClassLoader().getResourceAsStream(fileName)) {
properties.load(input);
} catch (IOException e) {
e.printStackTrace();
// Handle the exception correctly for your application
}
return properties;
}
}

View File

@ -1,26 +0,0 @@
package com.example.services;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseConnection implements AutoCloseable {
private Connection connection;
public DatabaseConnection(String dbHost, String username, String password) throws SQLException {
// Initialiser votre connexion à la base de données ici
connection = DriverManager.getConnection("jdbc:oracle:thin:@" + dbHost + ":1521/XSTORE", username, password);
}
public Connection getConnection() {
return connection;
}
@Override
public void close() throws SQLException {
if (connection != null && !connection.isClosed()) {
connection.close();
}
}
}

View File

@ -1,28 +0,0 @@
package com.example.services;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseConnectionDS implements AutoCloseable {
private Connection connection;
public DatabaseConnectionDS(String username, String password) throws SQLException {
// Initialiser votre connexion à la base de données ici
// jdbc:oracle:thin:@v-aspd-b01-ii-d.adic.lan:1521/IASPDI
// jdbc:oracle:thin:@v-aspd-b01-irdc.adic.lan:1521/MASPDI
connection = DriverManager.getConnection("jdbc:oracle:thin:@v-aspd-b01-irdc.adic.lan:1521/MASPDI", username, password);
}
public Connection getConnection() {
return connection;
}
@Override
public void close() throws SQLException {
if (connection != null && !connection.isClosed()) {
connection.close();
}
}
}

View File

@ -26,7 +26,7 @@ public class DatabaseService {
DriverManager.setLoginTimeout(5); // Définir le timeout à 5 secondes
try (DatabaseConnection databaseConnection = new DatabaseConnection(dbHost, "repqueue", "repqueue")) {
try (DatabaseConnectXSTORE databaseConnection = new DatabaseConnectXSTORE(dbHost, "repqueue")) {
String query = "SELECT COUNT(*) FROM CTL_REPLICATION_QUEUE";
try (PreparedStatement statement = databaseConnection.getConnection().prepareStatement(query);

View File

@ -8,6 +8,6 @@ public class HelloWebService {
@GET
public String sayHello() {
return "Hello, world!";
return "Hello, I'm here to serve you!";
}
}

View File

@ -38,7 +38,7 @@ public class ItemService {
DriverManager.setLoginTimeout(5); // Définir le timeout à 5 secondes
try (DatabaseConnection databaseConnection = new DatabaseConnection(dbHost, "dtv", "dtv")) {
try (DatabaseConnectXSTORE databaseConnection = new DatabaseConnectXSTORE(dbHost, "dtv")) {
String query = "SELECT * FROM ITM_ITEM WHERE ITEM_ID LIKE ?" ;
try (PreparedStatement statement = databaseConnection.getConnection().prepareStatement(query)) {

View File

@ -1,5 +1,7 @@
package com.example.services;
import com.example.services.store.*;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@ -22,9 +24,15 @@ import java.util.concurrent.locks.ReentrantLock;
@Path("/stores")
public class StoreService {
private static List<store> cachedStoreList;
private static List<Store> cachedStoreList;
private static final Lock cacheLock = new ReentrantLock();
/**
* Retrieves a store by its ID.
*
* @param storeId the ID of the store to retrieve
* @return a response containing the store information in JSON format
*/
@GET
@Path("/get")
@Produces(MediaType.APPLICATION_JSON)
@ -35,9 +43,7 @@ public class StoreService {
DriverManager.setLoginTimeout(5); // Définir le timeout à 5 secondes
// IASPDI com02 / B1Xto9pAbtBCOxuecG7W
// MASPDI com02 /
try (DatabaseConnectionDS databaseConnection = new DatabaseConnectionDS("com02", "B1Xto9pAbtBCOxuecG7W")) {
try (DatabaseConnectDOTSOFT databaseConnection = new DatabaseConnectDOTSOFT("com02")) {
String query = "SELECT id_structure,nom,'10.100.0.18' AS ip, tel1 AS telephone FROM structure WHERE id_structure = ?" ;
try (PreparedStatement statement = databaseConnection.getConnection().prepareStatement(query)) {
@ -45,7 +51,7 @@ public class StoreService {
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
store store = mapResultSetTostore(resultSet);
Store store = mapResultSetTostore(resultSet);
ObjectMapper objectMapper = new ObjectMapper();
String jsonResponse = objectMapper.writeValueAsString(store);
@ -60,22 +66,27 @@ public class StoreService {
String errorResponse = "{\"error\":\"" + e.getMessage() + "\"}";
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorResponse).build();
} catch (JsonProcessingException e) {
e.printStackTrace(); // Gérer les exceptions correctement dans un environnement de production
e.printStackTrace(); // Handle exceptions correctly in a production environment
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("{\"error\":\"Error processing JSON\"}").build();
}
}
/**
* Retrieves all stores from the database and returns them as a JSON response.
*
* @return A JSON response containing the list of stores
*/
@GET
@Path("/getAll")
@Produces(MediaType.APPLICATION_JSON)
public Response getAllStores() {
if (cachedStoreList == null) {
// Utilisation d'un verrou pour éviter que plusieurs requêtes déclenchent la récupération simultanée
// Use of a lock to prevent multiple requests from triggering simultaneous retrieval
cacheLock.lock();
try {
// Vérification à nouveau après avoir acquis le verrou
// Check again after acquiring the lock
if (cachedStoreList == null) {
// Récupérer depuis la base de données seulement si la liste n'est pas en cache
// Retrieve from database only if list is not cached
cachedStoreList = retrieveStoresFromDatabase();
}
} finally {
@ -98,10 +109,15 @@ public class StoreService {
}
}
private List<store> retrieveStoresFromDatabase() {
/**
* Retrieves stores from the database.
*
* @return a list of stores retrieved from the database
*/
private List<Store> retrieveStoresFromDatabase() {
DriverManager.setLoginTimeout(5); // Définir le timeout à 5 secondes
try (DatabaseConnectionDS databaseConnection = new DatabaseConnectionDS("com02", "B1Xto9pAbtBCOxuecG7W")) {
try (DatabaseConnectDOTSOFT databaseConnection = new DatabaseConnectDOTSOFT("com02")) {
String query = "SELECT st.id_structure, TRIM(st.nom) as nom, '10.100.0.18' AS ip, " +
"st.tel1 AS telephone " +
"FROM COM02.STRUCTURE st " +
@ -111,10 +127,10 @@ public class StoreService {
try (PreparedStatement statement = databaseConnection.getConnection().prepareStatement(query);
ResultSet resultSet = statement.executeQuery()) {
List<store> storeList = new ArrayList<>();
List<Store> storeList = new ArrayList<>();
while (resultSet.next()) {
store store = mapResultSetTostore(resultSet);
Store store = mapResultSetTostore(resultSet);
storeList.add(store);
}
@ -126,8 +142,15 @@ public class StoreService {
}
}
private store mapResultSetTostore(ResultSet resultSet) throws SQLException {
store store = new store();
/**
* Maps a ResultSet to a store object.
*
* @param resultSet the ResultSet containing the data to be mapped
* @return the store object with mapped data
* @throws SQLException if there is an error accessing the data from the ResultSet
*/
private Store mapResultSetTostore(ResultSet resultSet) throws SQLException {
Store store = new Store();
store.setId_structure(resultSet.getInt("ID_STRUCTURE"));
store.setNom(resultSet.getString("NOM"));
@ -137,43 +160,129 @@ public class StoreService {
return store;
}
public class store {
private Integer id_structure;
private String nom;
private String ip;
private String telephone;
public Integer getId_structure() {
return id_structure;
}
public void setId_structure(Integer id_structure) {
this.id_structure = id_structure;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
@GET
@Path("/getStoreDetails")
@Produces(MediaType.APPLICATION_JSON)
public Response getStoreDetails() {
try {
StoreDetails storeDetails = retrieveStoreDetailsFromDatabase();
if (storeDetails != null) {
ObjectMapper objectMapper = new ObjectMapper();
try {
String jsonResponse = objectMapper.writeValueAsString(storeDetails);
//System.out.println("JSON Response: " + jsonResponse); // Ajoutez ceci pour vérifier la sortie JSON
return Response.ok(jsonResponse).build();
} catch (JsonProcessingException e) {
e.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("{\"error\":\"Error converting StoreDetails to JSON\"}")
.build();
}
} else {
return Response.status(Response.Status.NOT_FOUND).entity("{\"error\":\"Store details not found\"}").build();
}
} catch (RuntimeException e) {
// Capture the RuntimeException to manage SQL errors
e.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("{\"error\":\"" + e.getMessage() + "\"}").build();
}
}
/**
* Retrieves storeDetails from the database.
*
* @return a list of stores retrieved from the database
*/
private StoreDetails retrieveStoreDetailsFromDatabase() {
DriverManager.setLoginTimeout(5);
StoreDetails storeDetails = new StoreDetails(); // Déclarer l'objet en dehors des blocs try
try (DatabaseConnectDOTSOFT databaseConnection = new DatabaseConnectDOTSOFT("com02")) {
// Partie Store
String storeQuery = "SELECT st.id_structure, TRIM(st.nom) as nom, '10.100.0.18' AS ip, " +
"st.tel1 AS telephone, 'https://mp4.ikksgroup.com/photos/1/6/5/7/3/16573-large.JPG' as photoLink " +
"FROM COM02.STRUCTURE st " +
"WHERE st.id_structure = 4";
try (PreparedStatement storeStatement = databaseConnection.getConnection().prepareStatement(storeQuery);
ResultSet storeResultSet = storeStatement.executeQuery()) {
if (storeResultSet.next()) {
Store store = mapResultSetToStore(storeResultSet);
storeDetails.setStore(store); // Définir la partie Store dans l'objet StoreDetails
// Faites quelque chose avec la partie Store
} else {
// Ajustez selon le comportement souhaité si aucun résultat n'est trouvé pour la partie Store
}
}
// Partie Réplication
String replicationQuery = "SELECT 1 AS replicationOk, " +
"5 AS pendingReplications, " +
"TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS minReplicationDate, " +
"TO_CHAR(SYSDATE + INTERVAL '1' DAY, 'YYYY-MM-DD HH24:MI:SS') AS maxReplicationDate " +
"FROM DUAL";
try (PreparedStatement storeStatement = databaseConnection.getConnection().prepareStatement(replicationQuery);
ResultSet storeReplicationResultSet = storeStatement.executeQuery()) {
if (storeReplicationResultSet.next()) {
StoreReplication storeReplication = mapResultSetToStoreReplication(storeReplicationResultSet);
storeDetails.setReplication(storeReplication);
} else {
// Ajustez selon le comportement souhaité si aucun résultat n'est trouvé pour la partie Store
}
}
// Partie Ticket
String ticketQuery = "SELECT 10 AS totalTicketsInCaisse, " +
"15 AS totalTicketsInBackOffice " +
"FROM DUAL";
try (PreparedStatement ticketStatement = databaseConnection.getConnection().prepareStatement(ticketQuery);
ResultSet ticketResultSet = ticketStatement.executeQuery()) {
if (ticketResultSet.next()) {
StoreTicket storeTicket = mapResultSetToStoreTicket(ticketResultSet);
storeDetails.setTickets(storeTicket);
} else {
// Ajustez selon le comportement souhaité si aucun résultat n'est trouvé pour la partie Ticket
}
}
} catch (SQLException e) {
e.printStackTrace();
// Gérer les exceptions correctement dans un environnement de production
}
// Retournez l'objet StoreDetails complet
return storeDetails;
}
private Store mapResultSetToStore(ResultSet resultSet) throws SQLException {
Integer id_structure = resultSet.getInt("id_structure");
String nom = resultSet.getString("nom");
String ip = resultSet.getString("ip");
String telephone = resultSet.getString("telephone");
String photoLink = resultSet.getString("photoLink");
return new Store(id_structure, nom, ip, telephone, photoLink);
}
private StoreReplication mapResultSetToStoreReplication(ResultSet resultSet) throws SQLException {
boolean replicationOk = resultSet.getBoolean("replicationOk");
int pendingReplications = resultSet.getInt("pendingReplications");
String minReplicationDate = resultSet.getString("minReplicationDate");
String maxReplicationDate = resultSet.getString("maxReplicationDate");
return new StoreReplication(replicationOk, pendingReplications, minReplicationDate, maxReplicationDate);
}
private StoreTicket mapResultSetToStoreTicket(ResultSet resultSet) throws SQLException {
int totalTicketsInCaisse = resultSet.getInt("totalTicketsInCaisse");
int totalTicketsInBackOffice = resultSet.getInt("totalTicketsInBackOffice");
return new StoreTicket(totalTicketsInCaisse, totalTicketsInBackOffice);
}
}

View File

@ -0,0 +1,62 @@
package com.example.services.store;
public class Store {
private Integer id_structure;
private String nom;
private String ip;
private String telephone;
private String photoLink;
// Default constructor
public Store() {}
// Constructor with parameters
public Store(Integer id_structure, String nom, String ip, String telephone, String photoLink) {
this.id_structure = id_structure;
this.nom = nom;
this.ip = ip;
this.telephone = telephone;
this.photoLink = photoLink;
}
public Integer getId_structure() {
return id_structure;
}
public void setId_structure(Integer id_structure) {
this.id_structure = id_structure;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getPhotoLink() {
return photoLink;
}
public void setPhotoLink(String photoLink) {
this.photoLink = photoLink;
}
}

View File

@ -0,0 +1,44 @@
package com.example.services.store;
public class StoreDetails {
private Store store;
private StoreReplication replication;
private StoreTicket tickets;
public StoreDetails() {
// Constructeur par défaut nécessaire pour la désérialisation JSON
}
public StoreDetails(Store store, StoreReplication replication, StoreTicket tickets) {
this.store = store;
this.replication = replication;
this.tickets = tickets;
}
public Store getStore() {
return store;
}
public void setStore(Store store) {
this.store = store;
}
public StoreReplication getReplication() {
return replication;
}
public void setReplication(StoreReplication replication) {
this.replication = replication;
}
public StoreTicket getTickets() {
return tickets;
}
public void setTickets(StoreTicket tickets) {
this.tickets = tickets;
}
// Ajoutez éventuellement d'autres méthodes ou personnalisez selon vos besoins
}

View File

@ -0,0 +1,55 @@
package com.example.services.store;
public class StoreReplication {
private boolean replicationOk; // Ajoutez les propriétés nécessaires pour la partie réplication
private int pendingReplications;
private String minReplicationDate;
private String maxReplicationDate;
// Constructeur par défaut
public StoreReplication() {
// Default constructor required for JSON deserialization
}
// Constructeur avec paramètres
public StoreReplication(boolean replicationOk, int pendingReplications, String minReplicationDate, String maxReplicationDate) {
this.replicationOk = replicationOk;
this.pendingReplications = pendingReplications;
this.minReplicationDate = minReplicationDate;
this.maxReplicationDate = maxReplicationDate;
}
// Getters et setters
public boolean isReplicationOk() {
return replicationOk;
}
public void setReplicationOk(boolean replicationOk) {
this.replicationOk = replicationOk;
}
public int getPendingReplications() {
return pendingReplications;
}
public void setPendingReplications(int pendingReplications) {
this.pendingReplications = pendingReplications;
}
public String getMinReplicationDate() {
return minReplicationDate;
}
public void setMinReplicationDate(String minReplicationDate) {
this.minReplicationDate = minReplicationDate;
}
public String getMaxReplicationDate() {
return maxReplicationDate;
}
public void setMaxReplicationDate(String maxReplicationDate) {
this.maxReplicationDate = maxReplicationDate;
}
}

View File

@ -0,0 +1,35 @@
package com.example.services.store;
public class StoreTicket {
private int cashRegisterTickets; // Ajoutez les propriétés nécessaires pour la partie tickets
private int backOfficeTickets;
// Constructeur par défaut
public StoreTicket() {
// Default constructor required for JSON deserialization
}
// Constructeur avec paramètres
public StoreTicket(int cashRegisterTickets, int backOfficeTickets) {
this.cashRegisterTickets = cashRegisterTickets;
this.backOfficeTickets = backOfficeTickets;
}
// Getters et setters
public int getCashRegisterTickets() {
return cashRegisterTickets;
}
public void setCashRegisterTickets(int cashRegisterTickets) {
this.cashRegisterTickets = cashRegisterTickets;
}
public int getBackOfficeTickets() {
return backOfficeTickets;
}
public void setBackOfficeTickets(int backOfficeTickets) {
this.backOfficeTickets = backOfficeTickets;
}
}

View File

@ -0,0 +1,19 @@
# Development environment settings (dev)
dev.db.url=jdbc:oracle:thin:@v-aspd-b01-irdc.adic.lan:1521/MASPDI
dev.db.oai.password=base
dev.db.com02.password=B1Xto9pAbtBCOxuecG7W
# Pre-production environment settings (preprod)
preprod.db.url=jdbc:oracle:thin:@v-aspd-b01-ii-d.adic.lan:1521/IASPDI
preprod.db.oai.password=base
preprod.db.com02.password=B1Xto9pAbtBCOxuecG7W
# Production environment settings (prod)
prod.db.url=jdbc:oracle:thin:@prod-host:1521/PRODDB
prod.db.oai.password=base
prod.db.com02.password=com20
# XSTORE environment settings
xstore.db.url=jdbc:oracle:thin:@HOST:1521/XSTORE
xstore.db.dtv.password=dtv
xstore.db.repqueue.password=repqueue

View File

@ -0,0 +1,2 @@
# Indicates the current environment (dev, preprod, prod, etc.).
environment=dev

View File

@ -0,0 +1,12 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>