Commit 86a8fca6 authored by DUHEM Aristide's avatar DUHEM Aristide
Browse files

Added rabbit mq alert for general city and a specific one (hardcoded)

parent 4e29e092
......@@ -3,18 +3,25 @@ networks:
services:
mariadb:
# image docker mariadb
image: 'mariadb:latest'
environment:
# root password
- MARIADB_ROOT_PASSWORD=root
# creation of the database and the user
command: --init-file /data/application/initdb.sql
# mounting the initdb.sql file
volumes:
- ./initdb.sql:/data/application/initdb.sql
# port mapping
ports:
- "3306:3306"
networks:
- spring-db
rabbitmq:
image: 'rabbitmq:3-management'
container_name: rabbitmq
environment:
- RABBITMQ_DEFAULT_USER=guest
- RABBITMQ_DEFAULT_PASS=guest
ports:
- "5672:5672" # RabbitMQ main service
- "15672:15672" # RabbitMQ Management UI
networks:
- spring-db
\ No newline at end of file
......@@ -67,6 +67,11 @@
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
......
package eu.telecomnancy.weather;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
// Define the exchange name
public static final String EXCHANGE_NAME = "weather-alerts";
// Define the general queue name
public static final String QUEUE_NAME = "city-alerts";
// Define the queue name for Essey-lès-Nancy
public static final String ESSEY_QUEUE_NAME = "essey-alerts";
// Define the routing key pattern (use a wildcard for city-specific routing keys)
public static final String ROUTING_KEY_PATTERN = "weather.routingkey.*";
// Define the routing key for Essey-lès-Nancy
public static final String ESSEY_ROUTING_KEY = "weather.routingkey.essey-lès-nancy";
// Create the exchange
@Bean
public TopicExchange weatherAlertsExchange() {
return new TopicExchange(EXCHANGE_NAME, true, false); // Durable exchange
}
// Create the general queue
@Bean
public Queue queueForCityAlerts() {
return new Queue(QUEUE_NAME, true); // Durable queue
}
// Create the queue for Essey-lès-Nancy
@Bean
public Queue queueForEsseyAlerts() {
return new Queue(ESSEY_QUEUE_NAME, true); // Durable queue
}
// Bind the general queue to the exchange with the wildcard routing key
@Bean
public Binding binding(Queue queueForCityAlerts, TopicExchange weatherAlertsExchange) {
return BindingBuilder.bind(queueForCityAlerts)
.to(weatherAlertsExchange)
.with(ROUTING_KEY_PATTERN); // Use the wildcard routing key
}
// Bind the Essey-lès-Nancy queue to the exchange with the specific routing key
@Bean
public Binding esseyBinding(Queue queueForEsseyAlerts, TopicExchange weatherAlertsExchange) {
return BindingBuilder.bind(queueForEsseyAlerts)
.to(weatherAlertsExchange)
.with(ESSEY_ROUTING_KEY); // Use the specific routing key for Essey-lès-Nancy
}
}
\ No newline at end of file
package eu.telecomnancy.weather;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class TemperatureAlertListener {
// Listener for the general city-alerts queue
@RabbitListener(queues = RabbitMQConfig.QUEUE_NAME)
public void receiveAlert(String message) {
System.out.println("Received general alert: " + message);
}
// Listener for the Essey-lès-Nancy alerts queue
@RabbitListener(queues = RabbitMQConfig.ESSEY_QUEUE_NAME)
public void receiveEsseyAlert(String message) {
System.out.println("Received Essey-lès-Nancy alert: " + message);
}
}
\ No newline at end of file
package eu.telecomnancy.weather;
import eu.telecomnancy.weather.model.City;
import eu.telecomnancy.weather.service.CityService;
import eu.telecomnancy.weather.service.TemperatureAlertService;
import eu.telecomnancy.weather.service.WeatherService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
......@@ -13,10 +18,15 @@ import org.springframework.web.bind.annotation.RestController;
@EnableScheduling
@SpringBootApplication
@RestController
public class WeatherApplication {
@GetMapping("/health")
public String healthCheck() {
return "Application is running";
public class WeatherApplication implements CommandLineRunner {
private final WeatherService weatherService;
private final CityService cityService;
private final TemperatureAlertService temperatureAlertService;
public WeatherApplication(WeatherService weatherService, CityService cityService, TemperatureAlertListener temperatureAlertListener, TemperatureAlertService temperatureAlertService) {
this.weatherService = weatherService;
this.cityService = cityService;
this.temperatureAlertService = temperatureAlertService;
}
public static void main(String[] args) throws InterruptedException {
......@@ -24,4 +34,15 @@ public class WeatherApplication {
// Prevent immediate shutdown
Thread.currentThread().join();
}
@Override
public void run(String... args) {
System.out.println("Manually triggering the WeatherService method...");
City city = new City("Essey-lès-Nancy",0.,0.);
cityService.saveCity(city.getName(), city.getLatitude(), city.getLongitude());
weatherService.saveWeatherData(city, 12.5,0.,0.,0.,0.);
temperatureAlertService.sendAlert("Essay-lès-Nancy", 12.5);
temperatureAlertService.sendAlert("Paris", 15.0);
}
}
package eu.telecomnancy.weather.service;
import eu.telecomnancy.weather.RabbitMQConfig;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
@Service
public class TemperatureAlertService {
private final RabbitTemplate rabbitTemplate;
public TemperatureAlertService(RabbitTemplate rabbitTemplate, RabbitMQConfig rabbitMQConfig) {
this.rabbitTemplate = rabbitTemplate;
}
public void sendAlert(String city, double temperature) {
String message = String.format("New temperature for %s: %.2f°C", city, temperature);
String routingKey = "weather.routingkey." + city.toLowerCase().replace(" ", "-"); // Dynamic routing key
rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME, routingKey, message);
System.out.println("Alert sent: " + message);
}
}
\ No newline at end of file
......@@ -23,16 +23,20 @@ public class WeatherService {
private final AddressComponentImpl addressComponent;
private final CityRepository cityRepository;
private final Gson gson;
private final TemperatureAlertService alertService;
private final CityService cityService;
public WeatherService(WeatherComponentImpl weatherComponent,
AddressComponentImpl addressComponent,
CityRepository cityRepository,
WeatherDataRepository weatherDataRepository) {
WeatherDataRepository weatherDataRepository, TemperatureAlertService alertService, CityService cityService) {
this.weatherComponent = weatherComponent;
this.addressComponent = addressComponent;
this.cityRepository = cityRepository;
this.weatherDataRepository = weatherDataRepository;
this.alertService = alertService;
this.gson = new Gson();
this.cityService = cityService;
}
/**
......@@ -105,10 +109,21 @@ public class WeatherService {
}
}
public WeatherData saveWeatherData(City city, String description, double temperature, double humidity, double pressure,
double windSpeed, double windDirection) {
public void saveWeatherData(City city, double temperature, double humidity, double pressure,
double windSpeed, double windDirection) {
// Ensure the city is saved first
Optional<City> persistedCity = cityRepository.findByName(city.getName());
if (!persistedCity.isPresent()) {
persistedCity = Optional.of(cityRepository.save(city));
}
// Now save the weather data with the persisted city
WeatherData weatherData = new WeatherData(temperature, humidity, pressure, windSpeed, windDirection,
LocalDateTime.now(), city);
return weatherDataRepository.save(weatherData);
LocalDateTime.now(), persistedCity.get());
weatherDataRepository.save(weatherData);
// Send alert after saving data
alertService.sendAlert(persistedCity.get().getName(), temperature);
}
}
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