diff --git a/README.md b/README.md
index f8a0a9f..aa1a97b 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,44 @@ compilazione dei timesheet tenendo in considerazione vincoli e suggerimenti che
UGov PJ UWeb Timesheet prevede la possibilità di inserire in una tabella di frontiera *Oracle* le informazioni relative a
tempo a lavoro e assenze che vengono prelevate via REST da un server ePAS.
+## Endpoint REST del servizio
+
+Questo servizio integra alcuni endpoint REST di amministrazione che permettono di lanciare su richiesta
+nuova richieste di sincronizzazione dei dati, oltre a vari task di amministrazione.
+Gli endpoint REST sono protetti tramite Basic Auth, con utente e password configurato tramite
+le application.properties del servizio, oppure tramite le variabili d'ambiente
+security.username,security.password nel caso di avvio tramite docker/docker-compose.
+
+# Visualizzazione task schedulati
+
+È possibile visualizzare le informazioni dei task cron schedulati per la sincronizzazone
+delle informazioni tra ePAS e le tabelle Oracle di UGOV PJ UWeb Timesheet.
+
+L'endpoint da consultare è **/actuator/scheduledtasks**.
+
+## Metriche del servizio
+
+Il servizio esporta alcune metriche in formato Prometheus, è possibile consultarle all'endpoint
+**/actuator/prometheus**.
+
+Le metriche presenti contengono anche le tempistiche di sincronizzazione di tutti i dati e dei
+singoli uffici, del tipo:
+
+```
+# HELP epas_sync_office_month_seconds Timer della sincronizzazione dei dati di un mese di un ufficio
+# TYPE epas_sync_office_month_seconds summary
+epas_sync_office_month_seconds_count{officeId="2",yearMonth="2024-01",} 1.0
+epas_sync_office_month_seconds_sum{officeId="2",yearMonth="2024-01",} 0.237913661
+epas_sync_office_month_seconds_count{officeId="2",yearMonth="2023-12",} 1.0
+epas_sync_office_month_seconds_sum{officeId="2",yearMonth="2023-12",} 0.287619208
+epas_sync_office_month_seconds_count{officeId="1",yearMonth="2024-02",} 1.0
+
+# HELP epas_sync_all_time_seconds Time taken to sync all the details
+# TYPE epas_sync_all_time_seconds summary
+epas_sync_all_time_seconds_count{class="it.cnr.iit.epas.timesheet.ugovpj.service.SyncService",exception="none",method="syncAll",} 1.0
+epas_sync_all_time_seconds_sum{class="it.cnr.iit.epas.timesheet.ugovpj.service.SyncService",exception="none",method="syncAll",} 6.734464188
+```
+
## 👏 Come Contribuire
E' possibile contribuire a questo progetto utilizzando le modalità standard della comunità opensource
@@ -25,4 +63,4 @@ E' possibile contribuire a questo progetto utilizzando le modalità standard del
ePAS - UGov PJ UWeb Timesheet è concesso in licenza GNU AFFERO GENERAL PUBLIC LICENSE, come si trova
nel file [LICENSE][l].
-[l]: https://github.com/consiglionazionaledellericerche/epas-ugov-pj-timesheet/blob/master/LICENSE
+[l]: https://github.com/consiglionazionaledellericerche/epas-ugov-pj-timesheet/blob/master/LICENSE
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 141a0c1..f4ff6e5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -36,6 +36,14 @@
org.springframework.boot
spring-boot-starter-quartz
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
org.flywaydb
flyway-core
diff --git a/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/config/SecurityFilter.java b/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/config/SecurityFilter.java
index bf52a21..c9e37b7 100644
--- a/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/config/SecurityFilter.java
+++ b/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/config/SecurityFilter.java
@@ -21,6 +21,7 @@
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
@@ -64,6 +65,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/v3/api-docs/**", "/swagger-ui/**").permitAll()
.anyRequest().authenticated())
+ .csrf(AbstractHttpConfigurer::disable)
.httpBasic(Customizer.withDefaults());
return http.build();
}
diff --git a/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/config/TimedAspectForPrometheus.java b/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/config/TimedAspectForPrometheus.java
new file mode 100644
index 0000000..d209d93
--- /dev/null
+++ b/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/config/TimedAspectForPrometheus.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 Consiglio Nazionale delle Ricerche
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package it.cnr.iit.epas.timesheet.ugovpj.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import io.micrometer.core.aop.TimedAspect;
+import io.micrometer.core.instrument.MeterRegistry;
+
+/**
+ * Registra il tempo delle invocazioni dei metodi in modo che possa
+ * essere utilizzato dal Prometheus.
+ */
+@Configuration
+public class TimedAspectForPrometheus {
+
+ @Bean
+ public TimedAspect timedAspect(MeterRegistry registry) {
+ return new TimedAspect(registry);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/service/SyncService.java b/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/service/SyncService.java
index 5d665e2..db4b315 100644
--- a/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/service/SyncService.java
+++ b/src/main/java/it/cnr/iit/epas/timesheet/ugovpj/service/SyncService.java
@@ -16,9 +16,24 @@
*/
package it.cnr.iit.epas.timesheet.ugovpj.service;
+import java.time.LocalDate;
+import java.time.YearMonth;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.springframework.stereotype.Service;
+
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+
+import io.micrometer.core.annotation.Timed;
+import io.micrometer.core.instrument.Gauge;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Timer;
import it.cnr.iit.epas.timesheet.ugovpj.client.EpasClient;
import it.cnr.iit.epas.timesheet.ugovpj.client.dto.PersonDayShowTerseDto;
import it.cnr.iit.epas.timesheet.ugovpj.client.dto.PersonMonthRecapDto;
@@ -28,17 +43,9 @@
import it.cnr.iit.epas.timesheet.ugovpj.model.TimeDetailType;
import it.cnr.iit.epas.timesheet.ugovpj.repo.PersonTimeDetailRepo;
import it.cnr.iit.epas.timesheet.ugovpj.repo.TimeDetailTypeRepo;
-import java.time.LocalDate;
-import java.time.YearMonth;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.val;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
/**
* Servizio con i metodi che effettuano la sincronizzazione dei dati del tempo a lavoro
@@ -57,6 +64,8 @@ public class SyncService {
private final EpasClient epasClient;
private final TimesheetConfig timesheetConfig;
+ private final MeterRegistry meterRegistry;
+
/**
* Sincronizza il dato del tempo a lavoro di una persona in un giorno specifico.
*/
@@ -150,6 +159,7 @@ public List syncOfficeMonth(
log.debug("Inizio sincronizzazione dell'ufficio id={} del {}, notBefore={}",
officeId, yearMonth, notBefore);
long startTime = System.currentTimeMillis();
+ Timer.Sample timer = Timer.start(meterRegistry);
List details = Lists.newArrayList();
val monthRecaps = epasClient.getMonthRecap(officeId, yearMonth.getYear(), yearMonth.getMonthValue());
monthRecaps.forEach(monthRecap -> {
@@ -157,6 +167,11 @@ public List syncOfficeMonth(
});
log.info("Terminata sincronizzazione dell'ufficio id={} del {} in {} secondi",
officeId, yearMonth, ((System.currentTimeMillis() - startTime) / 1000));
+ timer.stop(Timer.builder("epas_sync_office_month")
+ .description("Timer della sincronizzazione dei dati di un mese di un ufficio")
+ .tag("officeId", String.valueOf(officeId))
+ .tag("yearMonth", yearMonth.toString())
+ .register(meterRegistry));
return details;
}
@@ -173,6 +188,7 @@ public List syncMonth(YearMonth yearMonth, Optional
return details;
}
+ @Timed(value = "epas_sync_all_time", description = "Time taken to sync all the details")
public List syncAll() {
List details = Lists.newArrayList();
LocalDate startingDate = LocalDate.now().minusDays(timesheetConfig.getDaysInThePast());
@@ -180,9 +196,12 @@ public List syncAll() {
log.info("Starting synchronization since {}", startingDate);
YearMonth yearMonth = YearMonth.from(startingDate);
while (!yearMonth.isAfter(YearMonth.from(LocalDate.now()))) {
- syncMonth(yearMonth, Optional.of(startingDate));
+ details.addAll(syncMonth(yearMonth, Optional.of(startingDate)));
yearMonth = yearMonth.plusMonths(1);
}
+ Gauge.builder("epas_synch_details_count", () -> details.size())
+ .description("A current number of books in the system")
+ .register(meterRegistry);
log.info("Synchronization ended in {} seconds", ((System.currentTimeMillis() - startTime) / 1000));
return details;
}
@@ -190,5 +209,4 @@ public List syncAll() {
private Set timeDetailTypes() {
return typeRepo.findAll().stream().map(TimeDetailType::getCode).collect(Collectors.toSet());
}
-
}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 8ea5b69..ca15a58 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -19,6 +19,8 @@ springdoc.packagesToScan=it.cnr.iit.epas.timesheet
#logging
logging.level.it.cnr.iit.epas=DEBUG
+management.endpoints.web.exposure.include=info,health,prometheus,scheduledtasks
+
#Impostazioni dell'applicazione
# Informazioni per l'accesso di questo servizio ai servizi REST di ePAS