Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 src/main/java/ar/utn/ba/ddsi/mailing/Adapters/IAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ar.utn.ba.ddsi.mailing.Adapters;

public interface IAdapter {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ar.utn.ba.ddsi.mailing.controllers;

import ar.utn.ba.ddsi.mailing.services.IAlertasService;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/api/alertas")
public class AlertasController {

private final IAlertasService alertasService;

public AlertasController(IAlertasService alertasService) {
this.alertasService = alertasService;
}

@PostMapping("/procesar")
public Mono<Void> procesarAlertas() {
return alertasService.generarAlertasYAvisar();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ar.utn.ba.ddsi.mailing.controllers;

import ar.utn.ba.ddsi.mailing.models.entities.Clima;
import ar.utn.ba.ddsi.mailing.models.repositories.IClimaRepository;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/climas")
public class ClimaController {

private final IClimaRepository climaRepository;

public ClimaController(IClimaRepository climaRepository) {
this.climaRepository = climaRepository;
}

@PostMapping
public Clima guardarClima(@RequestBody Clima clima) {
return climaRepository.save(clima);
}
}

25 changes: 25 additions & 0 deletions src/main/java/ar/utn/ba/ddsi/mailing/models/entities/Alerta.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ar.utn.ba.ddsi.mailing.models.entities;

import ar.utn.ba.ddsi.mailing.models.entities.condiciones.Condicion;
import ar.utn.ba.ddsi.mailing.models.entities.condiciones.CondicionTemperatura;
import lombok.Getter;
import lombok.Setter;
import java.util.List;

@Getter
@Setter
public class Alerta {

private List<Condicion> condiciones;

public Alerta(List<Condicion> condiciones){
this.condiciones = condiciones;
}

public boolean cumpleCondiciones(Clima clima) {
return this.condiciones.stream().allMatch(condicion->condicion.seCumple(clima));
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ public Clima() {
this.fechaActualizacion = LocalDateTime.now();
this.procesado = false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ public Email(String destinatario, String remitente, String asunto, String conten

public void enviar() {
//TODO: Implementación pendiente. Podríamos usar adapters
//Tambien se me ocurre que lo correcto seria que este metodo estuviera en el service, no en una entidad de dominio, porque realiza cosas complejas y se conecta con el exterior, ya que se encarga de enviar mails fuera del sistema
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ar.utn.ba.ddsi.mailing.models.entities.condiciones;

import ar.utn.ba.ddsi.mailing.models.entities.Clima;
import ar.utn.ba.ddsi.mailing.models.entities.enums.Operacion;

public interface Condicion {
public abstract boolean seCumple(Clima clima);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ar.utn.ba.ddsi.mailing.models.entities.condiciones;

import ar.utn.ba.ddsi.mailing.models.entities.Clima;
import ar.utn.ba.ddsi.mailing.models.entities.enums.Operacion;

public class CondicionHumedad implements Condicion {
private Operacion operacion;
private Integer valorEsperado;

public CondicionHumedad(Operacion operacion, Integer valorEsperado) {
this.operacion = operacion;
this.valorEsperado = valorEsperado;
}

@Override
public boolean seCumple(Clima clima){
switch (this.operacion){

case IGUAL -> {
return clima.getHumedad().equals(this.valorEsperado);
}
case MENOR -> {
return clima.getHumedad() < this.valorEsperado;
}
case MAYOR -> {
return clima.getHumedad() > this.valorEsperado;
}
default -> throw new IllegalStateException("Unexpected value: " + this.operacion);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ar.utn.ba.ddsi.mailing.models.entities.condiciones;

import ar.utn.ba.ddsi.mailing.models.entities.Clima;
import ar.utn.ba.ddsi.mailing.models.entities.enums.Operacion;

public class CondicionTemperatura implements Condicion {
private Operacion operacion;
private Double valorEsperado;

public CondicionTemperatura(Operacion operacion, Double valorEsperado) {
this.operacion = operacion;
this.valorEsperado = valorEsperado;
}

@Override
public boolean seCumple(Clima clima){
switch (this.operacion){

case IGUAL -> {
return clima.getTemperaturaCelsius().equals(this.valorEsperado);
}
case MENOR -> {
return clima.getTemperaturaCelsius() < this.valorEsperado;
}
case MAYOR -> {
return clima.getTemperaturaCelsius() > this.valorEsperado;
}
default -> throw new IllegalStateException("Unexpected value: " + this.operacion);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ar.utn.ba.ddsi.mailing.models.entities.enums;

public enum Operacion {
MAYOR,
MENOR,
IGUAL
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package ar.utn.ba.ddsi.mailing.services.impl;

import ar.utn.ba.ddsi.mailing.models.entities.Alerta;
import ar.utn.ba.ddsi.mailing.models.entities.Clima;
import ar.utn.ba.ddsi.mailing.models.entities.Email;
import ar.utn.ba.ddsi.mailing.models.entities.condiciones.CondicionHumedad;
import ar.utn.ba.ddsi.mailing.models.entities.condiciones.CondicionTemperatura;
import ar.utn.ba.ddsi.mailing.models.entities.enums.Operacion;
import ar.utn.ba.ddsi.mailing.models.repositories.IClimaRepository;
import ar.utn.ba.ddsi.mailing.services.IAlertasService;
import org.slf4j.Logger;
Expand All @@ -15,9 +19,11 @@
@Service
public class AlertasService implements IAlertasService {
private static final Logger logger = LoggerFactory.getLogger(AlertasService.class);
private static final double TEMPERATURA_ALERTA = 35.0;
private static final int HUMEDAD_ALERTA = 60;

Alerta alerta = new Alerta(List.of(
new CondicionTemperatura(Operacion.MAYOR,35.0),
new CondicionHumedad(Operacion.MAYOR, 60)
));
private final IClimaRepository climaRepository;
private final EmailService emailService;
private final String remitente;
Expand All @@ -43,7 +49,7 @@ public Mono<Void> generarAlertasYAvisar() {
})
.flatMap(climas -> {
climas.stream()
.filter(this::cumpleCondicionesAlerta)
.filter(c-> alerta.cumpleCondiciones(c))
.forEach(this::generarYEnviarEmail);

// Marcar todos como procesados
Expand All @@ -61,12 +67,6 @@ public Mono<Void> generarAlertasYAvisar() {
.then();
}

private boolean cumpleCondicionesAlerta(Clima clima) {
//TODO: podríamos refactorizar el diseño para que no sea un simple método, pues puede ser más complejo
return clima.getTemperaturaCelsius() > TEMPERATURA_ALERTA &&
clima.getHumedad() > HUMEDAD_ALERTA;
}

private void generarYEnviarEmail(Clima clima) {
String asunto = "Alerta de Clima - Condiciones Extremas";
String mensaje = String.format(
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ spring.application.name=climalert
cron.expression=0 * * * * *

# WeatherAPI Configuration
weather.api.key=API-KEY-EXAMPLE
weather.api.key=dd7ce45856b54fe89f9164145252505
weather.api.base-url=http://api.weatherapi.com/v1

# Email Configuration
Expand Down