Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.4'
id 'org.springframework.boot' version '3.5.5'
id 'io.spring.dependency-management' version '1.1.3'
}

Expand Down Expand Up @@ -31,3 +31,14 @@ dependencies {
tasks.named('test') {
useJUnitPlatform()
}

jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
attributes 'Main-Class': 'com.booleanuk.api.Main'
}

from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
28 changes: 28 additions & 0 deletions src/main/docker/Docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
services:
app:
image: 'book-app:latest'
container_name: app
depends_on:
- db
ports:
- '4000:4000'
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mypostgresuser
- SPRING_DATASOURCE_USERNAME=mypostgresuser
- SPRING_DATASOURCE_PASSWORD=mypostgrespassword
- SPRING_JPA_HIBERNATE_DDL_AUTO=update

db:
image: 'postgres:latest'
container_name: db
ports:
- '5432:5432'
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=mypostgresuser
- POSTGRES_DATABASE=mypostgresuser
- POSTGRES_PASSWORD=mypostgrespassword

volumes:
db-data:
9 changes: 9 additions & 0 deletions src/main/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM mcr.microsoft.com/openjdk/jdk:21-ubuntu

WORKDIR /app

COPY java.docker.day.2-0.0.1.jar /app/java.docker.day.2-0.0.1.jar

EXPOSE 4000

ENTRYPOINT [ "java", "-jar", "java.docker.day.2-0.0.1.jar" ]
11 changes: 11 additions & 0 deletions src/main/java/com/booleanuk/api/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.booleanuk.api;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
59 changes: 59 additions & 0 deletions src/main/java/com/booleanuk/api/controller/AuthorController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.booleanuk.api.controller;

import com.booleanuk.api.model.Author;
import com.booleanuk.api.repository.AuthorRepository;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import java.util.List;

@RestController
@RequestMapping("authors")
public class AuthorController {
private final AuthorRepository repository;

public AuthorController(AuthorRepository repository) {
this.repository = repository;
}

@GetMapping
public ResponseEntity<List<Author>> getAll() {
return ResponseEntity.ok(this.repository.findAll());
}

@GetMapping("{id}")
public ResponseEntity<Author> getById(@PathVariable("id") Integer id) {
Author author = this.repository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find author with that id."));
return ResponseEntity.ok(author);
}

record PostAuthor(String first_name, String last_name, String email, boolean alive) {}

//@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public ResponseEntity<Author> create(@RequestBody PostAuthor request) {
Author author = new Author(request.first_name(), request.last_name(), request.email(), request.alive());
return new ResponseEntity<>(this.repository.save(author), HttpStatus.CREATED);
}

@PutMapping("{id}")
public ResponseEntity<Author> updateAuthor(@PathVariable int id, @RequestBody PostAuthor author) {
Author authorToUpdate = this.repository.findById(id).orElseThrow(
() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find author with that id."));
authorToUpdate.setFirstName(author.first_name());
authorToUpdate.setLastName(author.last_name());
authorToUpdate.setEmail(author.email());
authorToUpdate.setAlive(author.alive());
return new ResponseEntity<>(this.repository.save(authorToUpdate), HttpStatus.CREATED);
}

@DeleteMapping("{id}")
public ResponseEntity<Author> deleteAuthor(@PathVariable int id) {
Author authorToDelete = this.repository.findById(id).orElseThrow(
() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find author with that id."));
this.repository.delete(authorToDelete);
return ResponseEntity.ok(authorToDelete);
}
}
72 changes: 72 additions & 0 deletions src/main/java/com/booleanuk/api/controller/BookController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.booleanuk.api.controller;

import com.booleanuk.api.model.Author;
import com.booleanuk.api.model.Book;
import com.booleanuk.api.model.Publisher;
import com.booleanuk.api.repository.AuthorRepository;
import com.booleanuk.api.repository.BookRepository;
import com.booleanuk.api.repository.PublisherRepository;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import java.util.List;

@RestController
@RequestMapping("books")
public class BookController {
private final BookRepository repository;
private final AuthorRepository authorRepository;
private final PublisherRepository publisherRepository;

public BookController(BookRepository repository, AuthorRepository authorRepository, PublisherRepository publisherRepository) {
this.repository = repository;
this.authorRepository = authorRepository;
this.publisherRepository = publisherRepository;

}

@GetMapping
public ResponseEntity<List<Book>> getAll() {
return ResponseEntity.ok(this.repository.findAll());
}

@GetMapping("{id}")
public ResponseEntity<Book> getById(@PathVariable("id") Integer id) {
Book book = this.repository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find book with that id."));
return ResponseEntity.ok(book);
}

private record PostBook(String title, String genre, int author_id, int publisher_id) {}

//@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public ResponseEntity<Book> create(@RequestBody PostBook request) {
Author author = authorRepository.findById(request.author_id()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find author with that id."));
Publisher publisher = publisherRepository.findById(request.publisher_id()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find publisher with that id."));
Book book = new Book(request.title(), request.genre(), author, publisher);
return new ResponseEntity<>(this.repository.save(book), HttpStatus.CREATED);
}

@PutMapping("{id}")
public ResponseEntity<Book> updateBook(@PathVariable int id, @RequestBody PostBook book) {
Book bookToUpdate = this.repository.findById(id).orElseThrow(
() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find book with that id."));
Author author = authorRepository.findById(book.author_id()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find author with that id."));
Publisher publisher = publisherRepository.findById(book.publisher_id()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find publisher with that id."));
bookToUpdate.setTitle(book.title());
bookToUpdate.setGenre(book.genre());
bookToUpdate.setAuthor(author);
bookToUpdate.setPublisher(publisher);
return new ResponseEntity<>(this.repository.save(bookToUpdate), HttpStatus.CREATED);
}

@DeleteMapping("{id}")
public ResponseEntity<Book> deleteBook(@PathVariable int id) {
Book bookToDelete = this.repository.findById(id).orElseThrow(
() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find book with that id."));
this.repository.delete(bookToDelete);
return ResponseEntity.ok(bookToDelete);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.booleanuk.api.controller;

import com.booleanuk.api.model.Publisher;
import com.booleanuk.api.repository.PublisherRepository;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import java.util.List;

@RestController
@RequestMapping("publishers")
public class PublisherController {
private final PublisherRepository repository;

public PublisherController(PublisherRepository repository) {
this.repository = repository;
}

@GetMapping
public ResponseEntity<List<Publisher>> getAll() {
return ResponseEntity.ok(this.repository.findAll());
}

@GetMapping("{id}")
public ResponseEntity<Publisher> getById(@PathVariable("id") Integer id) {
Publisher publisher = this.repository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find publisher with that id."));
return ResponseEntity.ok(publisher);
}

//@ResponseStatus(HttpStatus.CREATED)
@PostMapping
public ResponseEntity<Publisher> create(@RequestBody Publisher request) {
Publisher publisher = new Publisher(request.getName(), request.getLocation());
return new ResponseEntity<>(this.repository.save(publisher), HttpStatus.CREATED);
}

@PutMapping("{id}")
public ResponseEntity<Publisher> updatePublisher(@PathVariable int id, @RequestBody Publisher publisher) {
Publisher publisherToUpdate = this.repository.findById(id).orElseThrow(
() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find publisher with that id."));
publisherToUpdate.setName(publisher.getName());
publisherToUpdate.setLocation(publisher.getLocation());
return new ResponseEntity<>(this.repository.save(publisherToUpdate), HttpStatus.CREATED);
}

@DeleteMapping("{id}")
public ResponseEntity<Publisher> deletePublisher(@PathVariable int id) {
Publisher publisherToDelete = this.repository.findById(id).orElseThrow(
() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Could not find publisher with that id."));
this.repository.delete(publisherToDelete);
return ResponseEntity.ok(publisherToDelete);
}
}
88 changes: 88 additions & 0 deletions src/main/java/com/booleanuk/api/model/Author.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.booleanuk.api.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;

import java.util.List;

@Entity
@Table(name="authors")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

@Column(name="first_name")
private String firstName;

@Column(name="last_name")
private String lastName;

@Column
private String email;

@Column
private boolean alive;

@OneToMany(mappedBy = "author")
@JsonIgnoreProperties({"author"})
private List<Book> books;

public Author() {
}

public Author(String firstName, String lastName, String email, boolean alive) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.alive = alive;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public boolean isAlive() {
return alive;
}

public void setAlive(boolean alive) {
this.alive = alive;
}

public List<Book> getBooks() {
return books;
}

public void setBooks(List<Book> books) {
this.books = books;
}
}
Loading