get holidays from external service
This commit is contained in:
12
pom.xml
12
pom.xml
@@ -73,6 +73,18 @@
|
|||||||
<groupId>io.quarkus</groupId>
|
<groupId>io.quarkus</groupId>
|
||||||
<artifactId>quarkus-container-image-docker</artifactId>
|
<artifactId>quarkus-container-image-docker</artifactId>
|
||||||
</dependency>
|
</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>
|
<dependency>
|
||||||
<groupId>io.quarkus</groupId>
|
<groupId>io.quarkus</groupId>
|
||||||
<artifactId>quarkus-junit5</artifactId>
|
<artifactId>quarkus-junit5</artifactId>
|
||||||
|
|||||||
23
src/main/java/de/mbremer/holiday/HolidayRestClient.java
Normal file
23
src/main/java/de/mbremer/holiday/HolidayRestClient.java
Normal 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);
|
||||||
|
}
|
||||||
32
src/main/java/de/mbremer/holiday/HolidayService.java
Normal file
32
src/main/java/de/mbremer/holiday/HolidayService.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
package de.mbremer.kalender;
|
package de.mbremer.kalender;
|
||||||
|
|
||||||
import de.mbremer.secutity.User;
|
import de.mbremer.secutity.User;
|
||||||
|
import de.mbremer.secutity.UserService;
|
||||||
import io.quarkus.qute.Location;
|
import io.quarkus.qute.Location;
|
||||||
import io.quarkus.qute.Template;
|
import io.quarkus.qute.Template;
|
||||||
import io.quarkus.qute.TemplateInstance;
|
import io.quarkus.qute.TemplateInstance;
|
||||||
import io.quarkus.security.identity.SecurityIdentity;
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
|
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
|
||||||
|
|
||||||
import javax.annotation.security.RolesAllowed;
|
import javax.annotation.security.RolesAllowed;
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
@@ -18,16 +19,18 @@ import java.time.LocalDate;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
@Path("/kalender")
|
@Path("/kalender")
|
||||||
@RolesAllowed({"USER", "ADMIN"})
|
@RolesAllowed({"USER", "ADMIN"})
|
||||||
|
@ApplicationScoped
|
||||||
public class KalenderResource {
|
public class KalenderResource {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Logger log;
|
Logger log;
|
||||||
@Inject
|
@Inject
|
||||||
SecurityIdentity identity;
|
UserService userService;
|
||||||
|
@Inject
|
||||||
|
KalenderService kalenderService;
|
||||||
@Inject
|
@Inject
|
||||||
Template kalenderpage;
|
Template kalenderpage;
|
||||||
@Inject
|
@Inject
|
||||||
@@ -40,7 +43,7 @@ public class KalenderResource {
|
|||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.TEXT_HTML)
|
@Produces(MediaType.TEXT_HTML)
|
||||||
public TemplateInstance kalender(@QueryParam("offset") @DefaultValue("0") int offsetInWeeks) {
|
public TemplateInstance kalender(@QueryParam("offset") @DefaultValue("0") int offsetInWeeks) {
|
||||||
List<KalenderTag> week = getWeek(offsetInWeeks);
|
List<KalenderTag> week = kalenderService.getWeek(offsetInWeeks);
|
||||||
|
|
||||||
return kalenderpage
|
return kalenderpage
|
||||||
.data("today", LocalDate.now())
|
.data("today", LocalDate.now())
|
||||||
@@ -48,24 +51,8 @@ public class KalenderResource {
|
|||||||
.data("week", week);
|
.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) {
|
private List<Event> getEvents(int offsetInWeeks) {
|
||||||
List<KalenderTag> week = getWeek(offsetInWeeks);
|
List<KalenderTag> week = kalenderService.getWeek(offsetInWeeks);
|
||||||
return week.stream()
|
return week.stream()
|
||||||
.filter(d -> d.isCurrentUserInOffice())
|
.filter(d -> d.isCurrentUserInOffice())
|
||||||
.map(d-> new Event(LocalDateTime.now(), d.getDay()))
|
.map(d-> new Event(LocalDateTime.now(), d.getDay()))
|
||||||
@@ -80,7 +67,7 @@ public class KalenderResource {
|
|||||||
@QueryParam("offset") int offsetInWeeks, @MultipartForm KalenderTagForm kalenderForm) {
|
@QueryParam("offset") int offsetInWeeks, @MultipartForm KalenderTagForm kalenderForm) {
|
||||||
LocalDate dayParsed = LocalDate.parse(day);
|
LocalDate dayParsed = LocalDate.parse(day);
|
||||||
|
|
||||||
User currentUser = getCurrentUser();
|
User currentUser = userService.getCurrentUser();
|
||||||
try {
|
try {
|
||||||
KalenderTag tag = KalenderTag.find("day", dayParsed).singleResult();
|
KalenderTag tag = KalenderTag.find("day", dayParsed).singleResult();
|
||||||
if (kalenderForm.isInOffice() && tag.getInOffice() == null) {
|
if (kalenderForm.isInOffice() && tag.getInOffice() == null) {
|
||||||
@@ -97,15 +84,13 @@ public class KalenderResource {
|
|||||||
return kalender(offsetInWeeks);
|
return kalender(offsetInWeeks);
|
||||||
}
|
}
|
||||||
|
|
||||||
private User getCurrentUser() {
|
// Exports
|
||||||
return User.find("username", identity.getPrincipal().getName()).singleResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.TEXT_PLAIN)
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
@Path("export/txt")
|
@Path("export/txt")
|
||||||
public TemplateInstance exportTxt(@QueryParam("offset") int offset) {
|
public TemplateInstance exportTxt(@QueryParam("offset") int offset) {
|
||||||
return textExport.data("week", getWeek(offset));
|
return textExport.data("week", kalenderService.getWeek(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|||||||
38
src/main/java/de/mbremer/kalender/KalenderService.java
Normal file
38
src/main/java/de/mbremer/kalender/KalenderService.java
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,8 +24,18 @@ public class KalenderTag extends PanacheEntity {
|
|||||||
private boolean currentUserInOffice;
|
private boolean currentUserInOffice;
|
||||||
@Transient
|
@Transient
|
||||||
private boolean today;
|
private boolean today;
|
||||||
|
@Transient
|
||||||
|
private String holidayname;
|
||||||
|
|
||||||
public KalenderTag(LocalDate day) {
|
public KalenderTag(LocalDate day) {
|
||||||
this.day = day;
|
this.day = day;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean istHoliday() {
|
||||||
|
return holidayname != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPast() {
|
||||||
|
return day.isBefore(LocalDate.now());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
|
|||||||
|
|
||||||
import javax.annotation.security.PermitAll;
|
import javax.annotation.security.PermitAll;
|
||||||
import javax.annotation.security.RolesAllowed;
|
import javax.annotation.security.RolesAllowed;
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
import javax.ws.rs.*;
|
import javax.ws.rs.*;
|
||||||
@@ -21,6 +22,7 @@ import static de.mbremer.secutity.Role.ADMIN;
|
|||||||
|
|
||||||
@Path("/user")
|
@Path("/user")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
|
@ApplicationScoped
|
||||||
public class UserResource {
|
public class UserResource {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|||||||
19
src/main/java/de/mbremer/secutity/UserService.java
Normal file
19
src/main/java/de/mbremer/secutity/UserService.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
%prod.quarkus.datasource.jdbc.url = jdbc:postgresql://${POSTGRES_HOST:db}:${POSTGRES_PORT:5432}/buerokalender
|
%prod.quarkus.datasource.jdbc.url = jdbc:postgresql://${POSTGRES_HOST:db}:${POSTGRES_PORT:5432}/buerokalender
|
||||||
%prod.quarkus.datasource.username = ${POSTGRES_USER:buerokalender}
|
%prod.quarkus.datasource.username = ${POSTGRES_USER:buerokalender}
|
||||||
%prod.quarkus.datasource.password = ${POSTGRES_PASSWORD:buerokalender}
|
%prod.quarkus.datasource.password = ${POSTGRES_PASSWORD:buerokalender}
|
||||||
|
# max JDBC pool size
|
||||||
%prod.quarkus.datasource.jdbc.max-size=16
|
%prod.quarkus.datasource.jdbc.max-size=16
|
||||||
quarkus.datasource.db-kind=postgresql
|
quarkus.datasource.db-kind=postgresql
|
||||||
|
|
||||||
@@ -15,6 +16,10 @@ quarkus.http.auth.form.enabled=true
|
|||||||
# 24h
|
# 24h
|
||||||
quarkus.http.auth.form.timeout=86400
|
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
|
# Deployment
|
||||||
quarkus.container-image.additional-tags= 1
|
quarkus.container-image.additional-tags= 1
|
||||||
quarkus.container-image.group = mattbremer
|
quarkus.container-image.group = mattbremer
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
<form action="/kalender/inoffice/{day.day}?offset={offset}" method="POST" name="kalenderForm" enctype="multipart/form-data">
|
<form action="/kalender/inoffice/{day.day}?offset={offset}" method="POST" name="kalenderForm" enctype="multipart/form-data">
|
||||||
<div class="form-check form-switch">
|
<div class="form-check form-switch">
|
||||||
<input class="form-check-input" type="checkbox" name="inoffice" onchange="this.form.submit()"
|
<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} >
|
{#if day.isCurrentUserInOffice}checked{/if} >
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
{day.day.formatCommon}
|
{day.day.formatCommon}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
{#if day.istHoliday}{day.holidayname}{/if}
|
||||||
{#if day.inOffice}{day.inOffice.username}{/if}
|
{#if day.inOffice}{day.inOffice.username}{/if}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ class KalenderResourceTest {
|
|||||||
|
|
||||||
@InjectMock
|
@InjectMock
|
||||||
SecurityIdentity identity;
|
SecurityIdentity identity;
|
||||||
|
@InjectMock
|
||||||
|
KalenderService kalenderService;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestSecurity(authorizationEnabled = false)
|
@TestSecurity(authorizationEnabled = false)
|
||||||
|
|||||||
Reference in New Issue
Block a user