-
Notifications
You must be signed in to change notification settings - Fork 3
WIP: review #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jqno
wants to merge
106
commits into
review
Choose a base branch
from
master
base: review
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
WIP: review #1
Changes from all commits
Commits
Show all changes
106 commits
Select commit
Hold shift + click to select a range
c89c27b
Adds a build script
jqno ea1889c
Adds Hello World app
jqno 6879ae4
Enables Heroku deployment
jqno dbdf7b7
Adds logging
jqno 69776a4
Adds Travis CI script
jqno ce96cc2
Disallows annotations
jqno 244b081
Modularise this bad boy
jqno 2a3cfe7
Applies architecture
jqno d04d16c
Applies more architecture
jqno d28d955
Applies architecture to logger
jqno 25d6292
Adds Architecture tests (in JUnit 3 for now)
jqno 53ab5ed
Adds tests for Heroku and Endpoints
jqno 5cd05af
Adds test for SparkServer
jqno 1d9baf0
Don't deploy test dependencies
jqno 6346823
Switches to PicoTest with AssertJ
jqno d6a21dc
Enables CORS
jqno b40b5bf
Sets up before/afterAll for SparkServerTest
jqno 46813ca
Adds JaCoCo to build
jqno 5344445
Adds unit test for CORS
jqno 15226ca
Moves tests to correct package
jqno f1d86d9
Adds test for Slf4jLogger
jqno 9c0af8b
Makes the build less chatty
jqno e8dd87a
Extracts Endpoints interface
jqno a202469
Adds Todo domain class
jqno 0e0eefc
Adds Serializer
jqno 2b3e2c4
Refactors ArchitectureTest
jqno 493515a
Renames hello endpoint to todo
jqno f73dcb0
Extracts Request to its own class
jqno b278cc0
Implements POST endpoint
jqno 96edf5a
Small refactoring
jqno aedd1bb
Adds logs script
jqno e3a14b7
Renames EndpointsTest to DefaultEndpointsTest
jqno 6ba04d2
Implements DELETE endpoint
jqno f79bed0
Extracts assertSingleCall method
jqno 23bbdda
Adds toString to Todo
jqno fb97542
Implements serializer for lists of Todos
jqno 91083fc
Implements GET endpoint to replace helloworld
jqno 5e9928f
Fixes NoClassDefError in gson
jqno e49b557
Adds InMemoryRepository
jqno 242db69
Uses Repository to store Todos in Endpoints
jqno bfe5b7c
Introduces PartialTodo
jqno 8f23dd3
Reorganises TestData
jqno 2abadc8
Fixes serialization for PartialTodos
jqno ec0054a
Adds support for partial Todo to POST
jqno 3e97c50
Adds logging to Endpoints
jqno cf8167d
Makes all PartialTodo fields optional
jqno 0913cc9
Adds logging to InMemoryRepository
jqno 36878f7
Adds logging to GsonSerializer
jqno bf31eda
ಠ_ಠ
jqno 4007193
Responds with the actual Todo after a POST
jqno 53dfc6f
Returns correct URL from POST
jqno fb1244f
Switches from int to UUID for ids
jqno 296ab19
Renames Endpoints to Controller
jqno e16970e
Simplifies Controller by removing Route and Request
jqno 4a59e37
Adds GET endpoint with id
jqno f7b4af5
Cleans up wiring of loggers
jqno 98fb1d5
Refactors WiredApplication
jqno 911686f
Updates coverage threshold
jqno e3f0cab
Implements PATCH endpoint
jqno b480478
Implements DELETE with id endpoint
jqno 8447500
Implements dealing with order
jqno 7feaa1f
Adds CORS tests for all endpoints
jqno ec60781
Simplifies patch logic
jqno f3a8f08
Start with adding error handling
jqno ea5b42a
Adds error handling to controller
jqno 26d756f
Differentiates between invalid requests and internal server errors
jqno 1c94c72
Allows for failures in Repository
jqno 7405d56
Improves naming
jqno 2cb7356
Flips ifs around for readability
jqno 9d2a4f0
Restructures wiring
jqno 450430a
Restructures test wiring
jqno 57ba636
Renames DefaultWiring to Wiring
jqno 341d5c3
Turns Heroku into a proper interface with implementation
jqno e9dd055
Adds invalid data to TestData
jqno f8d4cb5
Adds tests for failure cases in DefaultController
jqno 16661d0
Sets coverage of everything except wiring to 100%
jqno ab14483
Makes slf4j-api dependency explicit
jqno fd481ba
Moves InMemoryRepository to a separate package
jqno c0d5f6e
Adds Database dependencies
jqno b68df97
Adds initial empty DatabaseRepository
jqno 1963da3
Wires in jdbc url and logger
jqno 089b440
Adds architecture test for Jdbi
jqno 69f5877
Integrates AssertJ-vavr
jqno 4a08f10
Adds test to assert that repo initialization is idempotent
jqno 8987d5a
Implements initial database round-trip
jqno 04d72b1
Generates URL from todo and implements GET
jqno 6ec72ca
Implements the rest of the database queries
jqno 5c21db4
Removes placeholder tests
jqno 6fc48f9
Adds some failure logging to DatabaseRepository
jqno ad1d211
Adds PostgreSQL dependency
jqno a65ba50
Fixes PostgreSQL conversion issue
jqno 94d4076
Adds test for failure case
jqno 25b90a0
Consolidates environment default constants
jqno 1b579b3
Factors out Wired class
jqno d92b924
Names Repository methods more consistently
jqno 2750172
Adds Runner
jqno 721e1ca
Adds a thread safety warning
jqno d64fe9e
Adds a README.md
jqno 31ab938
Fixes architecture test when run from IntelliJ
jqno 2a8e82e
Makes it possible to run locally with H2
jqno af90ac2
Makes various small improvements
jqno cb4c8f8
Makes repo initialization failures testable
jqno a16bb91
Adds a banner
jqno 44ba2a5
Adds transaction support for updates
jqno 81ab5df
Renames Jdbi to Engine
jqno fe7004f
Update README.md
jqno File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <extensions> | ||
| <extension> | ||
| <groupId>io.takari.polyglot</groupId> | ||
| <artifactId>polyglot-yaml</artifactId> | ||
| <version>0.3.2</version> | ||
| </extension> | ||
| </extensions> | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| language: java | ||
| jdk: openjdk11 | ||
| script: mvn clean verify |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| web: java $JAVA_OPTS -p ./target/parallel-java-1.0.jar:./target/dependency -m nl.jqno.paralleljava/nl.jqno.paralleljava.Main |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Parallel Java | ||
|
|
||
| [](https://travis-ci.org/jqno/paralleljava) | ||
|
|
||
| This app is written in Java from a Parallel Universe where annotations were never invented. You can check: there isn't a single annotation in this codebase! | ||
|
|
||
| It requires a JDK 11 to build and run. | ||
|
|
||
| It's a showcase for my talk, Java from a Parallel Universe. It's also a fully functioning [Todo Backend](https://www.todobackend.com/) (you can [run the Todo Backend test suite](https://www.todobackend.com/specs/index.html?https://parallel-java.herokuapp.com/todo | ||
| )!), using the [Spark web framework](http://sparkjava.com/), the [Jdbi database framework](http://jdbi.org/), and **no framework** for dependency injection because you really really don't need one. It also uses Java 11 `var` declarations, [Vavr](http://www.vavr.io/) and [Polyglot for Maven](https://github.com/takari/polyglot-maven) because I think they're pretty nifty and because they make the code look a little different, as if, I dunno, as if it came from a Parallel Universe or something? Also, the application is fully modularized and has 100% test coverage because why not. | ||
|
|
||
| Note, however, that this is still a demo app that is not production-ready. Some corners have definitely been cut. For example, the [InMemoryRepository](https://github.com/jqno/paralleljava/blob/master/src/main/java/nl/jqno/paralleljava/app/persistence/inmemory/InMemoryRepository.java) is not thread-safe. | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| <?xml version="1.0"?> | ||
| <!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> | ||
|
|
||
| <module name = "Checker"> | ||
| <property name="charset" value="UTF-8"/> | ||
| <property name="severity" value="error"/> | ||
|
|
||
| <module name="TreeWalker"> | ||
| <module name="Regexp"> | ||
| <property name="format" value="@"/> | ||
| <property name="illegalPattern" value="true"/> | ||
| <property name="ignoreComments" value="true"/> | ||
| <property name="message" value="Annotations are not allowed!"/> | ||
| </module> | ||
| </module> | ||
| </module> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| modelVersion: 4.0.0 | ||
| groupId: nl.jqno.paralleljava | ||
| artifactId: parallel-java | ||
| version: 1.0 | ||
| packaging: jar | ||
|
|
||
| name: parallel-java | ||
| description: "Todo-Backend built with Java from a Parallel Universe: a demo project to illustrate the point of my talk 'Java from a Parallel Universe'" | ||
|
|
||
| properties: { | ||
| encoding: utf-8, | ||
| maven.compiler.source: 11, | ||
| maven.compiler.target: 11, | ||
| coverage.threshold: 1.0 | ||
| } | ||
|
|
||
| repositories: | ||
| - { id: bintray-jqno-picotest-repo, url: "https://dl.bintray.com/jqno/picotest-repo" } | ||
|
|
||
| dependencyManagement: | ||
| dependencies: | ||
| - { groupId: org.jdbi, artifactId: jdbi3-bom, version: 3.6.0, type: pom, scope: import } | ||
|
|
||
| dependencies: | ||
| - { groupId: io.vavr, artifactId: vavr, version: 0.10.0 } | ||
| - { groupId: io.vavr, artifactId: vavr-gson, version: 0.10.0 } | ||
| - { groupId: com.sparkjava, artifactId: spark-core, version: 2.7.2 } | ||
| - { groupId: org.slf4j, artifactId: slf4j-api, version: 1.7.26 } | ||
| - { groupId: org.slf4j, artifactId: slf4j-simple, version: 1.7.26 } | ||
| - { groupId: com.google.code.gson, artifactId: gson, version: 2.8.5 } | ||
| - { groupId: org.jdbi, artifactId: jdbi3-core } | ||
| - { groupId: org.jdbi, artifactId: jdbi3-vavr } | ||
| - { groupId: org.postgresql, artifactId: postgresql, version: 42.2.5 } | ||
| - { groupId: com.h2database, artifactId: h2, version: 1.4.199 } | ||
|
|
||
| - { groupId: nl.jqno.picotest, artifactId: picotest, version: 0.3, scope: test } | ||
| - { groupId: nl.jqno.equalsverifier, artifactId: equalsverifier, version: 3.1.7, scope: test } | ||
| - { groupId: org.assertj, artifactId: assertj-core, version: 3.11.1, scope: test } | ||
| - { groupId: org.assertj, artifactId: assertj-vavr, version: 0.1.0, scope: test } | ||
| - { groupId: com.tngtech.archunit, artifactId: archunit, version: 0.9.3, scope: test } | ||
|
|
||
| # REST-Assured is useful but problematic on Java 11. We need to overrule Groovy and exclude JAXB-OSGI. | ||
| - { groupId: org.codehaus.groovy, artifactId: groovy, version: 2.5.6, scope: test } | ||
| - { groupId: org.codehaus.groovy, artifactId: groovy-xml, version: 2.5.6, scope: test } | ||
| - groupId: io.rest-assured | ||
| artifactId: rest-assured | ||
| version: 3.3.0 | ||
| scope: test | ||
| exclusions: | ||
| - groupId: com.sun.xml.bind | ||
| artifactId: jaxb-osgi | ||
|
|
||
| build: | ||
| plugins: | ||
| - groupId: org.apache.maven.plugins | ||
| artifactId: maven-compiler-plugin | ||
| version: 3.8.0 | ||
|
|
||
| - groupId: org.apache.maven.plugins | ||
| artifactId: maven-surefire-plugin | ||
| version: 2.22.1 | ||
| configuration: | ||
| argLine: "@{argLine} --add-opens nl.jqno.paralleljava/nl.jqno.paralleljava.app.domain=ALL-UNNAMED" | ||
|
|
||
| - groupId: org.apache.maven.plugins | ||
| artifactId: maven-dependency-plugin | ||
| version: 3.1.1 | ||
| configuration: | ||
| includeScope: runtime | ||
| executions: | ||
| - id: default | ||
| phase: package | ||
| goals: [copy-dependencies] | ||
|
|
||
| - groupId: org.apache.maven.plugins | ||
| artifactId: maven-checkstyle-plugin | ||
| version: 3.0.0 | ||
| dependencies: | ||
| - { groupId: com.puppycrawl.tools, artifactId: checkstyle, version: 8.18 } | ||
| configuration: | ||
| configLocation: checkstyle.xml | ||
| includeTestSourceDirectory: true | ||
| encoding: UTF-8 | ||
| consoleOutput: true | ||
| excludes: "**/module-info.java" | ||
| executions: | ||
| - id: default | ||
| phase: verify | ||
| goals: [check] | ||
| configuration: | ||
| failsOnError: true | ||
|
|
||
| - groupId: org.jacoco | ||
| artifactId: jacoco-maven-plugin | ||
| version: 0.8.3 | ||
| configuration: | ||
| excludes: | ||
| - "nl/jqno/paralleljava/Main.class" | ||
| executions: | ||
| - id: default-prepare-angent | ||
| goals: [prepare-agent] | ||
| - id: default-report | ||
| goals: [report] | ||
| - id: default-check | ||
| goals: [check] | ||
| configuration: | ||
| rules: | ||
| - element: BUNDLE | ||
| limits: | ||
| - counter: INSTRUCTION | ||
| value: COVEREDRATIO | ||
| minimum: ${coverage.threshold} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| git push -f heroku master |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| mvn clean verify | ||
| mvn jacoco:report | ||
| open target/site/jacoco/index.html | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| heroku logs --tail --source app | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| module nl.jqno.paralleljava { | ||
| exports nl.jqno.paralleljava; | ||
|
|
||
| opens nl.jqno.paralleljava.app.domain to gson; | ||
|
|
||
| requires io.vavr; | ||
| requires io.vavr.gson; | ||
| requires jdbi3.core; | ||
| requires jdbi3.vavr; | ||
| requires java.sql; // required for gson | ||
| requires gson; | ||
| requires slf4j.api; | ||
| requires spark.core; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package nl.jqno.paralleljava; | ||
|
|
||
| import io.vavr.collection.HashMap; | ||
| import nl.jqno.paralleljava.app.Runner; | ||
| import nl.jqno.paralleljava.app.controller.DefaultController; | ||
| import nl.jqno.paralleljava.app.environment.Environment; | ||
| import nl.jqno.paralleljava.app.environment.HerokuEnvironment; | ||
| import nl.jqno.paralleljava.app.logging.LoggerFactory; | ||
| import nl.jqno.paralleljava.app.logging.Slf4jLogger; | ||
| import nl.jqno.paralleljava.app.persistence.RandomIdGenerator; | ||
| import nl.jqno.paralleljava.app.persistence.database.DatabaseRepository; | ||
| import nl.jqno.paralleljava.app.persistence.database.JdbiEngine; | ||
| import nl.jqno.paralleljava.app.persistence.database.TodoMapper; | ||
| import nl.jqno.paralleljava.app.serialization.GsonSerializer; | ||
| import nl.jqno.paralleljava.app.server.SparkServer; | ||
|
|
||
| public class Main { | ||
| public static void main(String... args) { | ||
| LoggerFactory loggerFactory = c -> new Slf4jLogger(org.slf4j.LoggerFactory.getLogger(c)); | ||
|
|
||
| var processBuilder = new ProcessBuilder(); | ||
| var environmentMap = HashMap.ofAll(processBuilder.environment()); | ||
| var environment = new HerokuEnvironment(environmentMap); | ||
|
|
||
| var fullUrl = environment.hostUrl().getOrElse(Environment.DEFAULT_URL) + Environment.ENDPOINT; | ||
| var port = environment.port().getOrElse(Environment.DEFAULT_PORT); | ||
| var jdbcUrl = environment.jdbcUrl().getOrElse(Environment.DEFAULT_JDBC_URL); | ||
|
|
||
| var todoMapper = new TodoMapper(fullUrl); | ||
| var dbEngine = new JdbiEngine(jdbcUrl, todoMapper, loggerFactory); | ||
| var repository = new DatabaseRepository(dbEngine); | ||
|
|
||
| var idGenerator = new RandomIdGenerator(); | ||
| var serializer = GsonSerializer.create(loggerFactory); | ||
| var controller = new DefaultController(fullUrl, repository, idGenerator, serializer, loggerFactory); | ||
| var server = new SparkServer(Environment.ENDPOINT, port, controller, loggerFactory); | ||
|
|
||
| var runner = new Runner(repository, server, loggerFactory); | ||
| runner.startup(); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package nl.jqno.paralleljava.app; | ||
|
|
||
| import nl.jqno.paralleljava.app.logging.Logger; | ||
| import nl.jqno.paralleljava.app.logging.LoggerFactory; | ||
| import nl.jqno.paralleljava.app.persistence.Repository; | ||
| import nl.jqno.paralleljava.app.server.Server; | ||
|
|
||
| public class Runner { | ||
| private final Repository repository; | ||
| private final Server server; | ||
| private final Logger logger; | ||
|
|
||
| public Runner(Repository repository, Server server, LoggerFactory loggerFactory) { | ||
| this.repository = repository; | ||
| this.server = server; | ||
| this.logger = loggerFactory.create(getClass()); | ||
| } | ||
|
|
||
| public void startup() { | ||
| repository.initialize() | ||
| .onSuccess(ignored -> { | ||
| printBanner(); | ||
| server.run(); | ||
| }); | ||
| } | ||
|
|
||
| private void printBanner() { | ||
| logger.forProduction(" _ _ _____ _ _ __ _ _"); | ||
| logger.forProduction("| \\ | | ___ | ___| __ __ _ _ __ ___ _____ _____ _ __| | _| |\\ \\ \\ \\"); | ||
| logger.forProduction("| \\| |/ _ \\ | |_ | '__/ _` | '_ ` _ \\ / _ \\ \\ /\\ / / _ \\| '__| |/ / | \\ \\ \\ \\"); | ||
| logger.forProduction("| |\\ | (_) | | _|| | | (_| | | | | | | __/\\ V V / (_) | | | <|_| ) ) ) )"); | ||
| logger.forProduction("|_| \\_|\\___/ |_| |_| \\__,_|_| |_| |_|\\___| \\_/\\_/ \\___/|_| |_|\\_(_) / / / /"); | ||
| logger.forProduction("=======================================================================/_/_/_/"); | ||
| logger.forProduction(" :: Built with Plain Java! :: \uD83C\uDF89"); | ||
| } | ||
| } |
12 changes: 12 additions & 0 deletions
12
src/main/java/nl/jqno/paralleljava/app/controller/Controller.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package nl.jqno.paralleljava.app.controller; | ||
|
|
||
| import io.vavr.control.Try; | ||
|
|
||
| public interface Controller { | ||
| Try<String> get(); | ||
| Try<String> get(String id); | ||
| Try<String> post(String json); | ||
| Try<String> patch(String id, String json); | ||
| Try<String> delete(); | ||
| Try<String> delete(String id); | ||
| } |
97 changes: 97 additions & 0 deletions
97
src/main/java/nl/jqno/paralleljava/app/controller/DefaultController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| package nl.jqno.paralleljava.app.controller; | ||
|
|
||
| import io.vavr.Function1; | ||
| import io.vavr.control.Try; | ||
| import nl.jqno.paralleljava.app.domain.Todo; | ||
| import nl.jqno.paralleljava.app.logging.Logger; | ||
| import nl.jqno.paralleljava.app.logging.LoggerFactory; | ||
| import nl.jqno.paralleljava.app.persistence.IdGenerator; | ||
| import nl.jqno.paralleljava.app.persistence.Repository; | ||
| import nl.jqno.paralleljava.app.serialization.Serializer; | ||
|
|
||
| import java.util.UUID; | ||
|
|
||
| public class DefaultController implements Controller { | ||
| private final String url; | ||
| private final Repository repository; | ||
| private final IdGenerator idGenerator; | ||
| private final Serializer serializer; | ||
jqno marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| private final Logger logger; | ||
|
|
||
| public DefaultController(String url, Repository repository, IdGenerator idGenerator, Serializer serializer, LoggerFactory loggerFactory) { | ||
| this.url = url; | ||
| this.repository = repository; | ||
| this.idGenerator = idGenerator; | ||
| this.serializer = serializer; | ||
| this.logger = loggerFactory.create(getClass()); | ||
| } | ||
|
|
||
| public Try<String> get() { | ||
| return repository.getAll() | ||
| .map(serializer::serializeTodos); | ||
| } | ||
|
|
||
| public Try<String> get(String id) { | ||
| var uuid = serializer.deserializeUuid(id); | ||
| if (uuid.isEmpty()) { | ||
| return Try.failure(new IllegalArgumentException("Invalid GET request: " + id)); | ||
| } | ||
|
|
||
| return repository | ||
| .get(uuid.get()) | ||
| .flatMap(o -> o.map(serializer::serializeTodo).toTry(() -> new IllegalArgumentException("Cannot find " + id))); | ||
| } | ||
|
|
||
| public Try<String> post(String json) { | ||
| logger.forProduction("POSTed: " + json); | ||
| var partialTodo = serializer.deserializePartialTodo(json); | ||
| if (partialTodo.isEmpty() || partialTodo.get().title().isEmpty()) { | ||
| return Try.failure(new IllegalArgumentException("Invalid POST request: " + json)); | ||
| } | ||
|
|
||
| var pt = partialTodo.get(); | ||
| var id = idGenerator.generateId(); | ||
| var todo = new Todo(id, pt.title().get(), buildUrlFor(id), false, pt.order().getOrElse(0)); | ||
| return repository.create(todo) | ||
| .map(ignored -> serializer.serializeTodo(todo)); | ||
| } | ||
|
|
||
| public Try<String> patch(String id, String json) { | ||
| logger.forProduction("PATCHed: " + json); | ||
| var uuid = serializer.deserializeUuid(id); | ||
| var partialTodo = serializer.deserializePartialTodo(json); | ||
| if (uuid.isEmpty() || partialTodo.isEmpty()) { | ||
| return Try.failure(new IllegalArgumentException("Invalid PATCH request: " + id + ", " + json)); | ||
| } | ||
|
|
||
| var pt = partialTodo.get(); | ||
| Function1<Todo, Todo> updater = todo -> new Todo( | ||
| todo.id(), | ||
| pt.title().getOrElse(todo.title()), | ||
| todo.url(), | ||
| pt.completed().getOrElse(todo.completed()), | ||
| pt.order().getOrElse(todo.order()) | ||
| ); | ||
| return repository.update(uuid.get(), updater) | ||
| .map(serializer::serializeTodo); | ||
| } | ||
|
|
||
| public Try<String> delete() { | ||
| return repository.deleteAll() | ||
| .map(ignored -> ""); | ||
| } | ||
|
|
||
| public Try<String> delete(String id) { | ||
| var uuid = serializer.deserializeUuid(id); | ||
| if (uuid.isEmpty()) { | ||
| return Try.failure(new IllegalArgumentException("Invalid DELETE request: " + id)); | ||
| } | ||
|
|
||
| return repository.delete(uuid.get()) | ||
| .map(ignored -> ""); | ||
| } | ||
|
|
||
| private String buildUrlFor(UUID id) { | ||
| return url + "/" + id.toString(); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.