diff --git a/kontor-javalin/build.gradle b/kontor-javalin/build.gradle index ab20966..ac0a44e 100644 --- a/kontor-javalin/build.gradle +++ b/kontor-javalin/build.gradle @@ -19,13 +19,18 @@ dependencies { implementation libs.hypersistence implementation libs.validation.api annotationProcessor libs.hibernate.jpamodelgen + implementation libs.el + annotationProcessor libs.openapi.annotation + implementation libs.javalin.openapi + implementation libs.javalin.swagger + implementation libs.javalin.redoc testImplementation(platform(libs.junit.bom)) testImplementation "org.junit.jupiter:junit-jupiter" } task fatJar(type: Jar) { manifest { - attributes 'Main-Class': 'de.thpeetz.kontor.api.Main' + attributes 'Main-Class': 'de.thpeetz.kontor.Main' } duplicatesStrategy = DuplicatesStrategy.EXCLUDE from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } diff --git a/kontor-javalin/gradle/libs.versions.toml b/kontor-javalin/gradle/libs.versions.toml index d51ec22..52732f5 100644 --- a/kontor-javalin/gradle/libs.versions.toml +++ b/kontor-javalin/gradle/libs.versions.toml @@ -14,6 +14,8 @@ postgresql = "42.7.3" hibernate = "7.0.5.Final" validation = "2.0.1.Final" hypersistence = "3.14.1" +el = "4.0.1" +openapi = "6.7.0-3" [libraries] junit = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" } @@ -30,4 +32,9 @@ hibernate = { module = "org.hibernate.orm:hibernate-core", version.ref = "hibern hibernate-jpamodelgen = { module = "org.hibernate.orm:hibernate-jpamodelgen", version.ref = "hibernate" } hibernate-validator = { module = "org.hibernate:hibernate-validator", version.ref = "hibernate" } validation-api = { module = "javax.validation:validation-api", version.ref = "validation" } +el = { module = "org.glassfish:jakarta.el", version.ref = "el" } hypersistence = { module = "io.hypersistence:hypersistence-utils-hibernate-70", version.ref = "hypersistence" } +javalin-openapi = { module = "io.javalin.community.openapi:javalin-openapi-plugin", version.ref = "openapi" } +javalin-swagger = { module = "io.javalin.community.openapi:javalin-swagger-plugin", version.ref = "openapi" } +javalin-redoc = { module = "io.javalin.community.openapi:javalin-redoc-plugin", version.ref = "openapi" } +openapi-annotation = { module = "io.javalin.community.openapi:openapi-annotation-processor", version.ref = "openapi" } \ No newline at end of file diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/JavalinApp.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/JavalinApp.java deleted file mode 100644 index abc2c0b..0000000 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/JavalinApp.java +++ /dev/null @@ -1,33 +0,0 @@ -package de.thpeetz.kontor; - -import io.javalin.Javalin; - -import static io.javalin.apibuilder.ApiBuilder.get; -import static io.javalin.apibuilder.ApiBuilder.path; -import static io.javalin.apibuilder.ApiBuilder.post; - -import java.util.HashMap; - -import de.thpeetz.kontor.web.ComicHandler; -import de.thpeetz.kontor.web.MediaFileHandler; - -public class JavalinApp { - - public static Javalin create() { - return Javalin.create((var config) -> config.router.apiBuilder(() -> { - path("/", () -> get(ctx -> ctx.json("Ok"))); - path("health", () -> get(ctx -> { - HashMap status = new HashMap<>(); - status.put("status", "ok"); - ctx.json(status); - })); - path("/api/v1/comics", () -> { - get(ComicHandler.listAll); - }); - path("/api/v1/media/files", () -> { - get(MediaFileHandler.listAll); - post(MediaFileHandler.save); - }); - })); - } -} diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/Main.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/Main.java index 3914320..690ce58 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/Main.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/Main.java @@ -1,14 +1,52 @@ package de.thpeetz.kontor; +import java.util.HashMap; +import java.util.LinkedList; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import de.thpeetz.kontor.infrastructure.AppHibernateConfig; +import io.javalin.Javalin; +import jakarta.persistence.EntityManager; + public class Main { private static Logger logger = LoggerFactory.getLogger(Main.class); private static short port = 8400; public static void main(String[] args) { - JavalinApp.create().start(port); + Javalin app = Javalin.create(config -> { + config.requestLogger.http((ctx, ms) -> { + var path = ctx.path(); + if (!path.equals("/health")) { + logger.info(ctx.path()); + } + }); + }); + app.get("/", ctx -> ctx.json("Ok")); + app.get("/health", ctx -> { + HashMap status = new HashMap<>(); + status.put("status", "ok"); + ctx.json(status); + }); + app.get("/api/v1/comics", ctx -> { + var result = new LinkedList<>(); + ctx.json(result); + }); + app.get("/api/v1/media/files", ctx -> { + var result = new LinkedList<>(); + ctx.json(result); + }); + app.before(ctx -> { + ctx.attribute("configuration", AppHibernateConfig.configuration()); + }); + app.after(ctx -> { + EntityManager entityManager = ctx.attribute("entityManager"); + if (entityManager != null) { + entityManager.close(); + } + }); + app.start(port); logger.info("API's alive for real :-)"); } diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/infrastructure/AppHibernateConfig.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/infrastructure/AppHibernateConfig.java index 0764187..7e51d3d 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/infrastructure/AppHibernateConfig.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/infrastructure/AppHibernateConfig.java @@ -22,8 +22,8 @@ import de.thpeetz.kontor.models.media.MediaArticle; import de.thpeetz.kontor.models.media.MediaFile; import de.thpeetz.kontor.models.media.MediaVideo; -class AppHibernateConfig { - static Configuration configuration() { +public class AppHibernateConfig { + public static Configuration configuration() { var configuration = new Configuration(); var settings = new Properties(); settings.put(AvailableSettings.JAKARTA_JDBC_DRIVER, "org.postgresql.Driver"); diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/infrastructure/AppHibernateSessionFactory.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/infrastructure/AppHibernateSessionFactory.java index 23ce217..ffe38b0 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/infrastructure/AppHibernateSessionFactory.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/infrastructure/AppHibernateSessionFactory.java @@ -7,13 +7,13 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -class AppHibernateSessionFactory { +public class AppHibernateSessionFactory { private static final Logger logger = LoggerFactory.getLogger(AppHibernateSessionFactory.class); private static SessionFactory sessionFactory; - static SessionFactory getSessionFactory() { + public static SessionFactory getSessionFactory() { if (Objects.isNull(sessionFactory)) { try { var configuration = AppHibernateConfig.configuration(); diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Comic.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Comic.java index a5e6436..abef62d 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Comic.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Comic.java @@ -43,16 +43,13 @@ public class Comic { @Column(unique = true, nullable = false) private String title; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "publisher_id") + @JoinColumn(name = "publisher_id", nullable = false) @JsonIgnoreProperties({ "comics" }) private Publisher publisher; - @Column private Boolean currentOrder = false; - @Column private Boolean completed = false; @Column(nullable = true) diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/ComicWork.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/ComicWork.java index 9f163d3..de26e74 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/ComicWork.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/ComicWork.java @@ -29,19 +29,16 @@ public class ComicWork { @Column(name = "last_modified_date") private Date lastModifiedDate; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "comic_id") + @JoinColumn(name = "comic_id", nullable = false) private Comic comic; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "artist_id") + @JoinColumn(name = "artist_id", nullable = false) private Artist artist; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "workType_id") + @JoinColumn(name = "workType_id", nullable = false) private Worktype workType; @Override diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Issue.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Issue.java index 63faa78..8942009 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Issue.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Issue.java @@ -42,21 +42,18 @@ public class Issue { @Column(name = "last_modified_date") private Date lastModifiedDate; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "comic_id") + @JoinColumn(name = "comic_id", nullable = false) @JsonIgnoreProperties({ "issues" }) private Comic comic; - @Column(nullable = true) @ManyToOne - @JoinColumn(name = "volume_id") + @JoinColumn(name = "volume_id", nullable = true) @JsonIgnoreProperties({ "issues" }) private Volume volume; - @Column(nullable = true) @ManyToOne - @JoinColumn(name = "storyArc_id") + @JoinColumn(name = "storyArc_id", nullable = true) @JsonIgnoreProperties({ "issues" }) private StoryArc storyArc; diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/IssueWork.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/IssueWork.java index 6de5d18..7ff4f63 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/IssueWork.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/IssueWork.java @@ -33,19 +33,16 @@ public class IssueWork { @Column(name = "last_modified_date") private Date lastModifiedDate; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "issue_id") + @JoinColumn(name = "issue_id", nullable = false) private Issue issue; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "artist_id") + @JoinColumn(name = "artist_id", nullable = false) private Artist artist; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "workType_id") + @JoinColumn(name = "workType_id", nullable = false) private Worktype workType; @Override diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Publisher.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Publisher.java index 58b5fea..58208e9 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Publisher.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Publisher.java @@ -44,13 +44,11 @@ public class Publisher { @Column(unique = true, nullable = false) private String name; - @Column private String weblink; - @Column(nullable = true) @JsonBackReference @ManyToOne - @JoinColumn(name = "parent_publisher_id") + @JoinColumn(name = "parent_publisher_id", nullable = true) @JsonIgnoreProperties({ "comics" }) private Publisher parentCompany; diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/StoryArc.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/StoryArc.java index 3f6604f..f62e14c 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/StoryArc.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/StoryArc.java @@ -43,15 +43,13 @@ public class StoryArc { @Column(nullable = false) private String name; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "comic_id") + @JoinColumn(name = "comic_id", nullable = false) @JsonIgnoreProperties({ "storyArcs" }) private Comic comic; - @Column(nullable = true) @ManyToOne - @JoinColumn(name = "volume_id") + @JoinColumn(name = "volume_id", nullable = true) @JsonIgnoreProperties({ "storyArcs" }) private Volume volume; diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/TradePaperback.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/TradePaperback.java index ddd1952..6299145 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/TradePaperback.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/TradePaperback.java @@ -36,13 +36,13 @@ public class TradePaperback { @Column(nullable = false) private String name; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "comic_id") + @JoinColumn(name = "comic_id", nullable = false) private Comic comic; @Column private Integer issueStart; @Column - private Integer issueEnd;} + private Integer issueEnd; +} diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Volume.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Volume.java index 0682445..056e541 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Volume.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/models/comics/Volume.java @@ -43,15 +43,14 @@ public class Volume { @Column(nullable = false) private String name; - @Column(nullable = false) @ManyToOne - @JoinColumn(name = "comic_id") + @JoinColumn(name = "comic_id", nullable = false) @JsonIgnoreProperties({ "volumes" }) private Comic comic; @Column(nullable = true) @OneToMany(fetch = FetchType.EAGER, mappedBy = "volume", cascade = CascadeType.REMOVE, orphanRemoval = true) - private List storyArcs = new LinkedList<>(); + private List storyArcs = new LinkedList<>(); @Column(nullable = true) @OneToMany(fetch = FetchType.EAGER, mappedBy = "volume", cascade = CascadeType.REMOVE, orphanRemoval = true) diff --git a/kontor-javalin/src/main/java/de/thpeetz/kontor/web/MediaFileHandler.java b/kontor-javalin/src/main/java/de/thpeetz/kontor/web/MediaFileHandler.java index b6cfe69..51504f7 100644 --- a/kontor-javalin/src/main/java/de/thpeetz/kontor/web/MediaFileHandler.java +++ b/kontor-javalin/src/main/java/de/thpeetz/kontor/web/MediaFileHandler.java @@ -1,20 +1,19 @@ package de.thpeetz.kontor.web; +import java.util.LinkedList; import java.util.List; import de.thpeetz.kontor.infrastructure.AppHibernate; import io.javalin.http.Handler; import io.javalin.http.HttpStatus; import de.thpeetz.kontor.models.media.MediaFile; -import de.thpeetz.kontor.models.media.MediaFileQueries; -import de.thpeetz.kontor.models.media.MediaFileQueries_; import de.thpeetz.kontor.web.model.NewMediaFile; import de.thpeetz.kontor.web.model.ResultMediaFile; public class MediaFileHandler { public static Handler listAll = (context) -> { - List result = AppHibernate.fromTransaction(MediaFileQueries_::getAllMediaFiles); + List result = new LinkedList<>(); context.json(new ResultMediaFile(result)); };