get holidays from external service

This commit is contained in:
mbremer
2021-07-31 14:48:09 +02:00
parent ccf130ad28
commit fd28303eb0
11 changed files with 156 additions and 26 deletions

12
pom.xml
View File

@@ -73,6 +73,18 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-container-image-docker</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client-jsonb</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jsonp</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>

View File

@@ -0,0 +1,23 @@
package de.mbremer.holiday;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import javax.json.JsonObject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
/**
* curl -H "X-DFA-Token: dfa" -X POST https://deutsche-feiertage-api.de/api/v1/2018-10-03
*/
@Path("/api/v1")
@RegisterRestClient
public interface HolidayRestClient {
/**
* @param date yyyy-MM-DD
*/
@POST
@Path("/{date}")
@Produces(MediaType.APPLICATION_JSON)
JsonObject getHoliday(@PathParam("date") String date, @HeaderParam("X-DFA-Token") String token);
}

View File

@@ -0,0 +1,32 @@
package de.mbremer.holiday;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.json.JsonObject;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
@ApplicationScoped
public class HolidayService {
private static final String TOKEN = "dfa";
@Inject
@RestClient
HolidayRestClient holidayRestClient;
/**
* @return Holiday name or null if it's not a holiday;
*/
public String getHolidayNiedersachsen(LocalDate date) {
// TODO Token via Filter
// TODO Fehlertolerant
// TODO Caching
// TODO Test via Wiremock
JsonObject holiday = holidayRestClient.getHoliday(date.format(DateTimeFormatter.ISO_DATE), TOKEN);
return holiday.getBoolean("result", false) && holiday.getJsonObject("holiday").getJsonObject("regions").getBoolean("ni", false) ?
holiday.getJsonObject("holiday").getString("name") : null;
}
}

View File

@@ -1,14 +1,15 @@
package de.mbremer.kalender;
import de.mbremer.secutity.User;
import de.mbremer.secutity.UserService;
import io.quarkus.qute.Location;
import io.quarkus.qute.Template;
import io.quarkus.qute.TemplateInstance;
import io.quarkus.security.identity.SecurityIdentity;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
import javax.annotation.security.RolesAllowed;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.NoResultException;
import javax.transaction.Transactional;
@@ -18,16 +19,18 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Path("/kalender")
@RolesAllowed({"USER", "ADMIN"})
@ApplicationScoped
public class KalenderResource {
@Inject
Logger log;
@Inject
SecurityIdentity identity;
UserService userService;
@Inject
KalenderService kalenderService;
@Inject
Template kalenderpage;
@Inject
@@ -40,7 +43,7 @@ public class KalenderResource {
@GET
@Produces(MediaType.TEXT_HTML)
public TemplateInstance kalender(@QueryParam("offset") @DefaultValue("0") int offsetInWeeks) {
List<KalenderTag> week = getWeek(offsetInWeeks);
List<KalenderTag> week = kalenderService.getWeek(offsetInWeeks);
return kalenderpage
.data("today", LocalDate.now())
@@ -48,24 +51,8 @@ public class KalenderResource {
.data("week", week);
}
private List<KalenderTag> getWeek(int offsetInWeeks) {
User currentUser = getCurrentUser();
LocalDate today = LocalDate.now();
LocalDate montag = today.minusDays(today.getDayOfWeek().getValue() - 1).plusDays(7 * offsetInWeeks);
return Stream.iterate(0, i -> i < 5, i -> ++i)
.map(d -> {
LocalDate day = montag.plusDays(d);
KalenderTag tag = (KalenderTag) KalenderTag.find("day", day).singleResultOptional().orElse(new KalenderTag(day));
tag.setCurrentUserInOffice(currentUser.equals(tag.getInOffice()));
tag.setToday(LocalDate.now().equals(day));
return tag;
})
.collect(Collectors.toList());
}
private List<Event> getEvents(int offsetInWeeks) {
List<KalenderTag> week = getWeek(offsetInWeeks);
List<KalenderTag> week = kalenderService.getWeek(offsetInWeeks);
return week.stream()
.filter(d -> d.isCurrentUserInOffice())
.map(d-> new Event(LocalDateTime.now(), d.getDay()))
@@ -80,7 +67,7 @@ public class KalenderResource {
@QueryParam("offset") int offsetInWeeks, @MultipartForm KalenderTagForm kalenderForm) {
LocalDate dayParsed = LocalDate.parse(day);
User currentUser = getCurrentUser();
User currentUser = userService.getCurrentUser();
try {
KalenderTag tag = KalenderTag.find("day", dayParsed).singleResult();
if (kalenderForm.isInOffice() && tag.getInOffice() == null) {
@@ -97,15 +84,13 @@ public class KalenderResource {
return kalender(offsetInWeeks);
}
private User getCurrentUser() {
return User.find("username", identity.getPrincipal().getName()).singleResult();
}
// Exports
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("export/txt")
public TemplateInstance exportTxt(@QueryParam("offset") int offset) {
return textExport.data("week", getWeek(offset));
return textExport.data("week", kalenderService.getWeek(offset));
}
@GET

View File

@@ -0,0 +1,38 @@
package de.mbremer.kalender;
import de.mbremer.holiday.HolidayService;
import de.mbremer.secutity.User;
import de.mbremer.secutity.UserService;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ApplicationScoped
public class KalenderService {
@Inject
UserService userService;
@Inject
HolidayService holidayService;
List<KalenderTag> getWeek(int offsetInWeeks) {
User currentUser = userService.getCurrentUser();
LocalDate today = LocalDate.now();
LocalDate montag = today.minusDays(today.getDayOfWeek().getValue() - 1).plusDays(7 * offsetInWeeks);
return Stream.iterate(0, i -> i < 5, i -> ++i)
.map(d -> {
LocalDate day = montag.plusDays(d);
KalenderTag tag = (KalenderTag) KalenderTag.find("day", day).singleResultOptional().orElse(new KalenderTag(day));
tag.setCurrentUserInOffice(currentUser.equals(tag.getInOffice()));
tag.setToday(LocalDate.now().equals(day));
tag.setHolidayname(holidayService.getHolidayNiedersachsen(day));
return tag;
})
.collect(Collectors.toList());
}
}

View File

@@ -24,8 +24,18 @@ public class KalenderTag extends PanacheEntity {
private boolean currentUserInOffice;
@Transient
private boolean today;
@Transient
private String holidayname;
public KalenderTag(LocalDate day) {
this.day = day;
}
public boolean istHoliday() {
return holidayname != null;
}
public boolean isPast() {
return day.isBefore(LocalDate.now());
}
}

View File

@@ -9,6 +9,7 @@ import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.*;
@@ -21,6 +22,7 @@ import static de.mbremer.secutity.Role.ADMIN;
@Path("/user")
@RolesAllowed("ADMIN")
@ApplicationScoped
public class UserResource {
@Inject

View File

@@ -0,0 +1,19 @@
package de.mbremer.secutity;
import io.quarkus.security.identity.SecurityIdentity;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
@RequestScoped
public class UserService {
@Inject
SecurityIdentity identity;
/**
* Returns the user currently logged in.
*/
public User getCurrentUser() {
return User.find("username", identity.getPrincipal().getName()).singleResult();
}
}

View File

@@ -2,6 +2,7 @@
%prod.quarkus.datasource.jdbc.url = jdbc:postgresql://${POSTGRES_HOST:db}:${POSTGRES_PORT:5432}/buerokalender
%prod.quarkus.datasource.username = ${POSTGRES_USER:buerokalender}
%prod.quarkus.datasource.password = ${POSTGRES_PASSWORD:buerokalender}
# max JDBC pool size
%prod.quarkus.datasource.jdbc.max-size=16
quarkus.datasource.db-kind=postgresql
@@ -15,6 +16,10 @@ quarkus.http.auth.form.enabled=true
# 24h
quarkus.http.auth.form.timeout=86400
# REST-CLient
de.mbremer.holiday.HolidayRestClient/mp-rest/url=https://deutsche-feiertage-api.de
de.mbremer.holiday.HolidayRestClient/mp-rest/scope=javax.inject.Singleton
# Deployment
quarkus.container-image.additional-tags= 1
quarkus.container-image.group = mattbremer

View File

@@ -40,6 +40,7 @@
<form action="/kalender/inoffice/{day.day}?offset={offset}" method="POST" name="kalenderForm" enctype="multipart/form-data">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" name="inoffice" onchange="this.form.submit()"
{#if day.isPast or day.istHoliday}disabled=""{/if}"
{#if day.isCurrentUserInOffice}checked{/if} >
</div>
</form>
@@ -48,6 +49,7 @@
{day.day.formatCommon}
</td>
<td>
{#if day.istHoliday}{day.holidayname}{/if}
{#if day.inOffice}{day.inOffice.username}{/if}
</td>

View File

@@ -22,6 +22,8 @@ class KalenderResourceTest {
@InjectMock
SecurityIdentity identity;
@InjectMock
KalenderService kalenderService;
@Test
@TestSecurity(authorizationEnabled = false)