diff --git a/apiGateway/src/main/java/com/library/apiGateway/configs/SecurityConfig.java b/apiGateway/src/main/java/com/library/apiGateway/configs/SecurityConfig.java index c884431..d87a119 100644 --- a/apiGateway/src/main/java/com/library/apiGateway/configs/SecurityConfig.java +++ b/apiGateway/src/main/java/com/library/apiGateway/configs/SecurityConfig.java @@ -24,6 +24,7 @@ public class SecurityConfig { // Public APIs "/book-service/api/books/**", + "/book-service/api/book/images/**", "/book-service/api/authors/**", "/book-service/api/publishers/**", "/book-service/api/genres/**", diff --git a/bookService/src/main/java/org/library/bookservice/config/SecurityConfig.java b/bookService/src/main/java/org/library/bookservice/config/SecurityConfig.java index 1fef808..a929b5a 100644 --- a/bookService/src/main/java/org/library/bookservice/config/SecurityConfig.java +++ b/bookService/src/main/java/org/library/bookservice/config/SecurityConfig.java @@ -46,6 +46,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .requestMatchers("/actuator/**").permitAll() .requestMatchers(HttpMethod.GET, "/api/books/**").permitAll() .requestMatchers("/api/books/**").hasRole("ADMIN") + .requestMatchers(HttpMethod.GET, "/api/book/images/**").permitAll() .requestMatchers(HttpMethod.GET, "/api/authors/**").permitAll() .requestMatchers("/api/authors/**").hasRole("ADMIN") .requestMatchers(HttpMethod.GET, "/api/publishers/**").permitAll() diff --git a/bookService/src/main/java/org/library/bookservice/config/WebConfig.java b/bookService/src/main/java/org/library/bookservice/config/WebConfig.java new file mode 100644 index 0000000..b49dbf1 --- /dev/null +++ b/bookService/src/main/java/org/library/bookservice/config/WebConfig.java @@ -0,0 +1,22 @@ +package org.library.bookservice.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Value("${data.book.images.location}") + private String imagesLocation; + + @Value("${data.book.images.path}") + private String imagesPath; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler(imagesPath + "**") + .addResourceLocations("file:" + imagesLocation); + } +} diff --git a/bookService/src/main/java/org/library/bookservice/datagen/BookSeedDto.java b/bookService/src/main/java/org/library/bookservice/datagen/BookSeedDto.java new file mode 100644 index 0000000..c91feed --- /dev/null +++ b/bookService/src/main/java/org/library/bookservice/datagen/BookSeedDto.java @@ -0,0 +1,21 @@ +package org.library.bookservice.datagen; + +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.List; + +@Data +public class BookSeedDto { + private String title; + private String isbn; + private String description; + private LocalDate releaseDate; + private BigDecimal price; + private String imageKey; + + private String category; + private String publisher; + private String author; + private List genres; +} \ No newline at end of file diff --git a/bookService/src/main/java/org/library/bookservice/datagen/TestDataGenerator.java b/bookService/src/main/java/org/library/bookservice/datagen/TestDataGenerator.java index aa9ce82..73ba800 100644 --- a/bookService/src/main/java/org/library/bookservice/datagen/TestDataGenerator.java +++ b/bookService/src/main/java/org/library/bookservice/datagen/TestDataGenerator.java @@ -1,19 +1,27 @@ package org.library.bookservice.datagen; -import lombok.AllArgsConstructor; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.library.bookservice.model.*; import org.library.bookservice.repository.*; -import jakarta.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import jakarta.annotation.PostConstruct; -import java.math.BigDecimal; -import java.time.LocalDate; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; -@AllArgsConstructor @Service +@RequiredArgsConstructor @Slf4j public class TestDataGenerator { @@ -22,240 +30,125 @@ public class TestDataGenerator { private final CategoryRepository categoryRepository; private final GenreRepository genreRepository; private final PublisherRepository publisherRepository; + private final ObjectMapper objectMapper; - @PostConstruct - private void initializeDbWithTestData() { - if (!bookRepository.findAll().isEmpty()) { - log.info("Skipped data generation. Database already contains data."); - return; - } - - // Create Categories - List categories = createCategories(); - categoryRepository.saveAll(categories); - log.info("Saved categories: " + categories); - - // Create Genres - List genres = createGenres(); - genreRepository.saveAll(genres); - log.info("Saved genres: " + genres); - - // Create Publishers - List publishers = createPublishers(); - publisherRepository.saveAll(publishers); - log.info("Saved publishers: " + publishers); - - // Create Authors and Books - List authors = createAuthors(); - authorRepository.saveAll(authors); - log.info("Saved authors: " + authors); - - createBooks(authors, categories, genres, publishers); - } - - private List createCategories() { - List categories = new ArrayList<>(); + @Value("${data.seeding.folder}") + private String seedingFolder; - Category fiction = new Category(); - fiction.setName("Fiction"); - fiction.setDescription("Fictional books"); - categories.add(fiction); + @Value("${data.seeding.categories}") + private String categoriesFile; - Category nonFiction = new Category(); - nonFiction.setName("Non-Fiction"); - nonFiction.setDescription("Non-fictional books"); - categories.add(nonFiction); + @Value("${data.seeding.genres}") + private String genresFile; - Category sciFi = new Category(); - sciFi.setName("Science Fiction"); - sciFi.setDescription("Sci-fi books"); - categories.add(sciFi); + @Value("${data.seeding.publishers}") + private String publishersFile; - Category fantasy = new Category(); - fantasy.setName("Fantasy"); - fantasy.setDescription("Fantasy books"); - categories.add(fantasy); + @Value("${data.seeding.authors}") + private String authorsFile; - Category biography = new Category(); - biography.setName("Biography"); - biography.setDescription("Biographies"); - categories.add(biography); + @Value("${data.seeding.books}") + private String booksFile; - Category selfHelp = new Category(); - selfHelp.setName("Self-Help"); - selfHelp.setDescription("Self-help books"); - categories.add(selfHelp); - - return categories; - } - - private List createGenres() { - List genres = new ArrayList<>(); - - Genre romance = new Genre(); - romance.setName("Romance"); - romance.setDescription("Romantic books"); - genres.add(romance); - - Genre thriller = new Genre(); - thriller.setName("Thriller"); - thriller.setDescription("Thrilling books"); - genres.add(thriller); - - Genre adventure = new Genre(); - adventure.setName("Adventure"); - adventure.setDescription("Adventure stories"); - genres.add(adventure); - - Genre mystery = new Genre(); - mystery.setName("Mystery"); - mystery.setDescription("Mystery novels"); - genres.add(mystery); - - Genre historical = new Genre(); - historical.setName("Historical"); - historical.setDescription("Historical literature"); - genres.add(historical); - - Genre horror = new Genre(); - horror.setName("Horror"); - horror.setDescription("Horror books"); - genres.add(horror); - - Genre fantasy = new Genre(); - fantasy.setName("Fantasy"); - fantasy.setDescription("Fantasy genre"); - genres.add(fantasy); - - return genres; - } - - private List createPublishers() { - List publishers = new ArrayList<>(); - - Publisher penguin = new Publisher(); - penguin.setName("Penguin Books"); - penguin.setAddress("123 Penguin Street"); - publishers.add(penguin); - - Publisher harperCollins = new Publisher(); - harperCollins.setName("HarperCollins"); - harperCollins.setAddress("456 Harper Avenue"); - publishers.add(harperCollins); - - Publisher simonSchuster = new Publisher(); - simonSchuster.setName("Simon & Schuster"); - simonSchuster.setAddress("789 Simon Road"); - publishers.add(simonSchuster); - - Publisher macmillan = new Publisher(); - macmillan.setName("Macmillan"); - macmillan.setAddress("101 Macmillan Boulevard"); - publishers.add(macmillan); - - Publisher randomHouse = new Publisher(); - randomHouse.setName("Random House"); - randomHouse.setAddress("102 Random Lane"); - publishers.add(randomHouse); - - return publishers; - } - - private List createAuthors() { - List authors = new ArrayList<>(); - - Author orwell = new Author(); - orwell.setName("George Orwell"); - orwell.setBio("Author of dystopian novels"); - authors.add(orwell); - - Author rowling = new Author(); - rowling.setName("J.K. Rowling"); - rowling.setBio("British author of the Harry Potter series"); - authors.add(rowling); - - Author king = new Author(); - king.setName("Stephen King"); - king.setBio("Author of horror novels"); - authors.add(king); - - Author austen = new Author(); - austen.setName("Jane Austen"); - austen.setBio("Known for novels about social issues"); - authors.add(austen); - - Author asimov = new Author(); - asimov.setName("Isaac Asimov"); - asimov.setBio("Author of science fiction and fantasy"); - authors.add(asimov); + @PostConstruct + public void initializeDbWithTestData() { + if (bookRepository.count() > 0) { + log.info("Database already initialized. Skipping data seeding."); + return; + } - return authors; + try { + List categories = loadData(categoriesFile, new TypeReference<>() { + }); + categories = categoryRepository.saveAll(categories); + log.info("Loaded {} categories", categories.size()); + + List genres = loadData(genresFile, new TypeReference<>() { + }); + genres = genreRepository.saveAll(genres); + log.info("Loaded {} genres", genres.size()); + + List publishers = loadData(publishersFile, new TypeReference<>() { + }); + publishers = publisherRepository.saveAll(publishers); + log.info("Loaded {} publishers", publishers.size()); + + List authors = loadData(authorsFile, new TypeReference<>() { + }); + authors = authorRepository.saveAll(authors); + log.info("Loaded {} authors", authors.size()); + + Map categoryMap = categories.stream() + .collect(Collectors.toMap(Category::getName, Function.identity())); + Map genreMap = genres.stream() + .collect(Collectors.toMap(Genre::getName, Function.identity())); + Map publisherMap = publishers.stream() + .collect(Collectors.toMap(Publisher::getName, Function.identity())); + Map authorMap = authors.stream() + .collect(Collectors.toMap(Author::getName, Function.identity())); + + List bookDtos = loadData(booksFile, new TypeReference<>() { + }); + List books = new ArrayList<>(); + + for (BookSeedDto dto : bookDtos) { + Book book = new Book(); + book.setTitle(dto.getTitle()); + book.setISBN(dto.getIsbn()); + book.setDescription(dto.getDescription()); + book.setReleaseDate(dto.getReleaseDate()); + book.setPrice(dto.getPrice()); + book.setImageKey(dto.getImageKey()); + + if (categoryMap.containsKey(dto.getCategory())) { + book.setCategory(categoryMap.get(dto.getCategory())); + } else { + log.warn("Category not found: {}", dto.getCategory()); + } + + if (publisherMap.containsKey(dto.getPublisher())) { + book.setPublisher(publisherMap.get(dto.getPublisher())); + } else { + log.warn("Publisher not found: {}", dto.getPublisher()); + } + + if (authorMap.containsKey(dto.getAuthor())) { + book.setAuthor(authorMap.get(dto.getAuthor())); + } else { + log.warn("Author not found: {}", dto.getAuthor()); + } + + if (dto.getGenres() != null) { + List bookGenres = dto.getGenres().stream() + .filter(genreMap::containsKey) + .map(genreMap::get) + .toList(); + book.setGenres(bookGenres); + } + + books.add(book); + } + + bookRepository.saveAll(books); + log.info("Successfully loaded {} books into database", books.size()); + + } catch (IOException e) { + log.error("Failed to seed data: {}", e.getMessage(), e); + throw new RuntimeException("Data seeding failed", e); + } } - private void createBooks(List authors, List categories, List genres, List publishers) { - List books = new ArrayList<>(); + /** + * Helper method to read JSON files. + * Автоматично об'єднує seedingFolder та fileName. + */ + private List loadData(String fileName, TypeReference> typeReference) throws IOException { + String fullPath = Paths.get(seedingFolder, fileName).toString(); - Book book1 = new Book(); - book1.setTitle("1984"); - book1.setAuthor(authors.get(0)); - book1.setCategory(categories.get(0)); - book1.setDescription("A dystopian novel"); - book1.setISBN("9780451524935"); - book1.setPublisher(publishers.get(0)); - book1.setReleaseDate(LocalDate.of(1949, 6, 8)); - book1.setPrice(BigDecimal.valueOf(15.99)); - book1.setGenres(List.of(genres.get(0), genres.get(3))); - books.add(book1); + log.debug("Reading data from file: {}", fullPath); - Book book2 = new Book(); - book2.setTitle("Harry Potter and the Philosopher's Stone"); - book2.setAuthor(authors.get(1)); - book2.setCategory(categories.get(3)); - book2.setDescription("A fantasy novel"); - book2.setISBN("9780747532743"); - book2.setPublisher(publishers.get(1)); - book2.setReleaseDate(LocalDate.of(1997, 6, 26)); - book2.setPrice(BigDecimal.valueOf(20.99)); - book2.setGenres(List.of(genres.get(6), genres.get(2))); - books.add(book2); - - Book book3 = new Book(); - book3.setTitle("The Shining"); - book3.setAuthor(authors.get(2)); - book3.setCategory(categories.get(2)); - book3.setDescription("A horror novel"); - book3.setISBN("9780307743657"); - book3.setPublisher(publishers.get(2)); - book3.setReleaseDate(LocalDate.of(1977, 1, 28)); - book3.setPrice(BigDecimal.valueOf(18.50)); - book3.setGenres(List.of(genres.get(5))); - books.add(book3); - - Book book4 = new Book(); - book4.setTitle("Pride and Prejudice"); - book4.setAuthor(authors.get(3)); - book4.setCategory(categories.get(0)); - book4.setDescription("A romantic novel"); - book4.setISBN("9780141439518"); - book4.setPublisher(publishers.get(3)); - book4.setReleaseDate(LocalDate.of(1813, 1, 28)); - book4.setPrice(BigDecimal.valueOf(12.99)); - book4.setGenres(List.of(genres.get(0), genres.get(4))); - books.add(book4); - - Book book5 = new Book(); - book5.setTitle("Foundation"); - book5.setAuthor(authors.get(4)); - book5.setCategory(categories.get(1)); - book5.setDescription("A science fiction novel"); - book5.setISBN("9780553293357"); - book5.setPublisher(publishers.get(4)); - book5.setReleaseDate(LocalDate.of(1951, 6, 1)); - book5.setPrice(BigDecimal.valueOf(16.99)); - book5.setGenres(List.of(genres.get(2), genres.get(6))); - books.add(book5); - - bookRepository.saveAll(books); - log.info("Saved books: " + books); + try (InputStream inputStream = new FileInputStream(fullPath)) { + return objectMapper.readValue(inputStream, typeReference); + } } -} +} \ No newline at end of file diff --git a/bookService/src/main/java/org/library/bookservice/dto/book/BookResponse.java b/bookService/src/main/java/org/library/bookservice/dto/book/BookResponse.java index 02fb8fd..8c01ab0 100644 --- a/bookService/src/main/java/org/library/bookservice/dto/book/BookResponse.java +++ b/bookService/src/main/java/org/library/bookservice/dto/book/BookResponse.java @@ -27,5 +27,6 @@ public class BookResponse extends AbstractResponse { private PublisherResponse publisher; private LocalDate releaseDate; private BigDecimal price; + private String imageUrl; private List bookGenres; } diff --git a/bookService/src/main/java/org/library/bookservice/mapper/BookMapper.java b/bookService/src/main/java/org/library/bookservice/mapper/BookMapper.java index 56abe59..5cebf93 100644 --- a/bookService/src/main/java/org/library/bookservice/mapper/BookMapper.java +++ b/bookService/src/main/java/org/library/bookservice/mapper/BookMapper.java @@ -1,6 +1,7 @@ package org.library.bookservice.mapper; import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; import org.library.bookservice.dto.book.BookRequest; import org.library.bookservice.dto.book.BookResponse; import org.library.bookservice.model.Book; @@ -9,6 +10,7 @@ import org.library.bookservice.service.CategoryService; import org.library.bookservice.service.GenreService; import org.library.bookservice.service.PublisherService; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -17,18 +19,24 @@ import java.util.Optional; @Service -@AllArgsConstructor +@RequiredArgsConstructor public class BookMapper implements Mapper { - private AuthorService authorService; - private CategoryService categoryService; - private PublisherService publisherService; - private GenreService genreService; + private final AuthorService authorService; + private final CategoryService categoryService; + private final PublisherService publisherService; + private final GenreService genreService; - private AuthorMapper authorMapper; - private CategoryMapper categoryMapper; - private PublisherMapper publisherMapper; - private GenreMapper genreMapper; + private final AuthorMapper authorMapper; + private final CategoryMapper categoryMapper; + private final PublisherMapper publisherMapper; + private final GenreMapper genreMapper; + + @Value("${data.book.images.url-host}") + private String imagesHost; + + @Value("${data.book.images.path}") + private String imagesPath; @Override public Book requestToEntity(BookRequest request, Optional id) { @@ -71,6 +79,7 @@ public BookResponse entityToResponse(Book entity) { .releaseDate(entity.getReleaseDate()) .price(entity.getPrice()) .bookGenres(genreMapper.entitiesToListResponse(entity.getGenres())) + .imageUrl(buildImageUrl(entity.getImageKey())) .build(); } @@ -79,4 +88,8 @@ public BookResponse entityToResponse(Book entity) { public List entitiesToListResponse(Collection entityList) { return entityList.stream().map(this::entityToResponse).toList(); } + + private String buildImageUrl(String key) { + return imagesHost + imagesPath + key; + } } diff --git a/bookService/src/main/java/org/library/bookservice/model/Book.java b/bookService/src/main/java/org/library/bookservice/model/Book.java index ab021c8..a710ad9 100644 --- a/bookService/src/main/java/org/library/bookservice/model/Book.java +++ b/bookService/src/main/java/org/library/bookservice/model/Book.java @@ -51,6 +51,9 @@ public class Book implements Identifiable, Archivable { ) private List genres = new ArrayList<>(); + @Column(name = "image_key") + private String imageKey; + @Column(nullable = false, columnDefinition = "TINYINT(1)") private boolean archived; } \ No newline at end of file diff --git a/bookService/src/main/resources/application-dev.yml b/bookService/src/main/resources/application-dev.yml index 96ba252..eb6e1fe 100644 --- a/bookService/src/main/resources/application-dev.yml +++ b/bookService/src/main/resources/application-dev.yml @@ -24,3 +24,11 @@ gateway: url: http://localhost:9000 review-service: url: http://localhost:8081 + +data: + book: + images: + location: ../data/book_images/ + url-host: http://localhost:8080 + seeding: + folder: ../data/seeding/ diff --git a/bookService/src/main/resources/application-prod.yml b/bookService/src/main/resources/application-prod.yml index 0abce7e..0603ea5 100644 --- a/bookService/src/main/resources/application-prod.yml +++ b/bookService/src/main/resources/application-prod.yml @@ -21,4 +21,11 @@ spring: gateway: url: http://api-gateway:9000 review-service: - url: http://review-service:8081 \ No newline at end of file + url: http://review-service:8081 + +data: + book: + images: /app/data/book_images/ + url-host: http://localhost:8080 + seeding: + folder: /app/data/seeding/ \ No newline at end of file diff --git a/bookService/src/main/resources/application.properties b/bookService/src/main/resources/application.properties index 532df2c..19cbb6f 100644 --- a/bookService/src/main/resources/application.properties +++ b/bookService/src/main/resources/application.properties @@ -16,3 +16,12 @@ logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG management.endpoints.web.exposure.include=health, metrics, prometheus management.endpoint.health.show-details=always + +data.seeding.categories=categories.json +data.seeding.genres=genres.json +data.seeding.publishers=publishers.json +data.seeding.authors=authors.json +data.seeding.books=books.json + +data.book.images.path=/api/book/images/ + diff --git a/bookService/src/main/resources/db/migration/V01__create_tables.sql b/bookService/src/main/resources/db/migration/V01__create_tables.sql index 391c885..c6cd561 100644 --- a/bookService/src/main/resources/db/migration/V01__create_tables.sql +++ b/bookService/src/main/resources/db/migration/V01__create_tables.sql @@ -9,7 +9,8 @@ CREATE TABLE book publisher_id INT, release_date DATE, price DECIMAL(10, 2), - archived BOOLEAN DEFAULT FALSE + archived BOOLEAN DEFAULT FALSE, + image_key VARCHAR(255) NOT NULL ); CREATE TABLE author diff --git a/data/book_images/1984.jpg b/data/book_images/1984.jpg new file mode 100644 index 0000000..0bb1034 Binary files /dev/null and b/data/book_images/1984.jpg differ diff --git a/data/book_images/alchemist.jpg b/data/book_images/alchemist.jpg new file mode 100644 index 0000000..966b1e3 Binary files /dev/null and b/data/book_images/alchemist.jpg differ diff --git a/data/book_images/atomic_habits.jpg b/data/book_images/atomic_habits.jpg new file mode 100644 index 0000000..3bd103d Binary files /dev/null and b/data/book_images/atomic_habits.jpg differ diff --git a/data/book_images/brave_new_world.jpg b/data/book_images/brave_new_world.jpg new file mode 100644 index 0000000..b4d4088 Binary files /dev/null and b/data/book_images/brave_new_world.jpg differ diff --git a/data/book_images/catcher_rye.jpg b/data/book_images/catcher_rye.jpg new file mode 100644 index 0000000..076c8bb Binary files /dev/null and b/data/book_images/catcher_rye.jpg differ diff --git a/data/book_images/clean_code.jpg b/data/book_images/clean_code.jpg new file mode 100644 index 0000000..4d03360 Binary files /dev/null and b/data/book_images/clean_code.jpg differ diff --git a/data/book_images/da_vinci_code.jpg b/data/book_images/da_vinci_code.jpg new file mode 100644 index 0000000..256022a Binary files /dev/null and b/data/book_images/da_vinci_code.jpg differ diff --git a/data/book_images/default.png b/data/book_images/default.png new file mode 100644 index 0000000..78132e4 Binary files /dev/null and b/data/book_images/default.png differ diff --git a/data/book_images/dune.jpg b/data/book_images/dune.jpg new file mode 100644 index 0000000..27b4055 Binary files /dev/null and b/data/book_images/dune.jpg differ diff --git a/data/book_images/fahrenheit_451.jpg b/data/book_images/fahrenheit_451.jpg new file mode 100644 index 0000000..01ab416 Binary files /dev/null and b/data/book_images/fahrenheit_451.jpg differ diff --git a/data/book_images/game_of_thrones.jpg b/data/book_images/game_of_thrones.jpg new file mode 100644 index 0000000..591413a Binary files /dev/null and b/data/book_images/game_of_thrones.jpg differ diff --git a/data/book_images/gone_girl.jpg b/data/book_images/gone_girl.jpg new file mode 100644 index 0000000..cc64266 Binary files /dev/null and b/data/book_images/gone_girl.jpg differ diff --git a/data/book_images/great_gatsby.jpg b/data/book_images/great_gatsby.jpg new file mode 100644 index 0000000..2aedcf7 Binary files /dev/null and b/data/book_images/great_gatsby.jpg differ diff --git a/data/book_images/harry_potter_1.jpg b/data/book_images/harry_potter_1.jpg new file mode 100644 index 0000000..6888ecf Binary files /dev/null and b/data/book_images/harry_potter_1.jpg differ diff --git a/data/book_images/it.jpg b/data/book_images/it.jpg new file mode 100644 index 0000000..1a12158 Binary files /dev/null and b/data/book_images/it.jpg differ diff --git a/data/book_images/lotr.jpg b/data/book_images/lotr.jpg new file mode 100644 index 0000000..70a4e3a Binary files /dev/null and b/data/book_images/lotr.jpg differ diff --git a/data/book_images/mockingbird.jpg b/data/book_images/mockingbird.jpg new file mode 100644 index 0000000..e2e4cc1 Binary files /dev/null and b/data/book_images/mockingbird.jpg differ diff --git a/data/book_images/orient_express.jpg b/data/book_images/orient_express.jpg new file mode 100644 index 0000000..2f31192 Binary files /dev/null and b/data/book_images/orient_express.jpg differ diff --git a/data/book_images/pride_and_prejudice.jpg b/data/book_images/pride_and_prejudice.jpg new file mode 100644 index 0000000..61921fa Binary files /dev/null and b/data/book_images/pride_and_prejudice.jpg differ diff --git a/data/book_images/sapiens.jpg b/data/book_images/sapiens.jpg new file mode 100644 index 0000000..a0da5c8 Binary files /dev/null and b/data/book_images/sapiens.jpg differ diff --git a/data/book_images/sherlock.jpg b/data/book_images/sherlock.jpg new file mode 100644 index 0000000..a04fb1a Binary files /dev/null and b/data/book_images/sherlock.jpg differ diff --git a/data/book_images/silent_patient.jpg b/data/book_images/silent_patient.jpg new file mode 100644 index 0000000..f57d704 Binary files /dev/null and b/data/book_images/silent_patient.jpg differ diff --git a/data/book_images/steve_jobs.jpg b/data/book_images/steve_jobs.jpg new file mode 100644 index 0000000..2c49014 Binary files /dev/null and b/data/book_images/steve_jobs.jpg differ diff --git a/data/book_images/the_hobbit.jpg b/data/book_images/the_hobbit.jpg new file mode 100644 index 0000000..a98c0e9 Binary files /dev/null and b/data/book_images/the_hobbit.jpg differ diff --git a/data/book_images/the_shining.jpg b/data/book_images/the_shining.jpg new file mode 100644 index 0000000..3af44ff Binary files /dev/null and b/data/book_images/the_shining.jpg differ diff --git a/data/book_images/thinking_fast.jpg b/data/book_images/thinking_fast.jpg new file mode 100644 index 0000000..8132be3 Binary files /dev/null and b/data/book_images/thinking_fast.jpg differ diff --git a/data/seeding/authors.json b/data/seeding/authors.json new file mode 100644 index 0000000..958e305 --- /dev/null +++ b/data/seeding/authors.json @@ -0,0 +1,25 @@ +[ + { "name": "George Orwell", "bio": "English novelist and critic." }, + { "name": "J.K. Rowling", "bio": "British author of the Harry Potter series." }, + { "name": "Stephen King", "bio": "The King of Horror." }, + { "name": "Jane Austen", "bio": "English novelist known for social commentary." }, + { "name": "F. Scott Fitzgerald", "bio": "American novelist of the Jazz Age." }, + { "name": "J.R.R. Tolkien", "bio": "The father of modern fantasy literature." }, + { "name": "Harper Lee", "bio": "Pulitzer Prize winner for To Kill a Mockingbird." }, + { "name": "Frank Herbert", "bio": "American science fiction author." }, + { "name": "Arthur Conan Doyle", "bio": "Creator of Sherlock Holmes." }, + { "name": "J.D. Salinger", "bio": "American writer known for his reclusive nature." }, + { "name": "Yuval Noah Harari", "bio": "Israeli public intellectual and historian." }, + { "name": "James Clear", "bio": "Writer focused on habits and decision making." }, + { "name": "Robert C. Martin", "bio": "Uncle Bob, software engineer and author." }, + { "name": "Dan Brown", "bio": "Author of thriller novels." }, + { "name": "George R.R. Martin", "bio": "Author of A Song of Ice and Fire." }, + { "name": "Agatha Christie", "bio": "The Queen of Mystery." }, + { "name": "Paulo Coelho", "bio": "Brazilian lyricist and novelist." }, + { "name": "Ray Bradbury", "bio": "American author and screenwriter." }, + { "name": "Gillian Flynn", "bio": "American author of thriller novels." }, + { "name": "Daniel Kahneman", "bio": "Nobel laureate in Economics." }, + { "name": "Walter Isaacson", "bio": "American journalist and biographer." }, + { "name": "Aldous Huxley", "bio": "English writer and philosopher." }, + { "name": "Alex Michaelides", "bio": "British-Cypriot author and screenwriter." } +] \ No newline at end of file diff --git a/data/seeding/books.json b/data/seeding/books.json new file mode 100644 index 0000000..f69d0d1 --- /dev/null +++ b/data/seeding/books.json @@ -0,0 +1,302 @@ +[ + { + "title": "1984", + "isbn": "9780451524935", + "description": "A chilling prophecy about the future.", + "releaseDate": "1949-06-08", + "price": 14.99, + "imageKey": "1984.jpg", + "category": "Fiction", + "publisher": "Penguin Books", + "author": "George Orwell", + "genres": ["Dystopian", "Science Fiction"] + }, + { + "title": "Harry Potter and the Sorcerer's Stone", + "isbn": "9780590353427", + "description": "The first book in the Harry Potter series.", + "releaseDate": "1997-06-26", + "price": 24.99, + "imageKey": "harry_potter_1.jpg", + "category": "Fiction", + "publisher": "Bloomsbury", + "author": "J.K. Rowling", + "genres": ["Fantasy", "Adventure"] + }, + { + "title": "The Shining", + "isbn": "9780307743657", + "description": "Jack Torrance's new job at the Overlook Hotel is the perfect chance for a fresh start.", + "releaseDate": "1977-01-28", + "price": 18.50, + "imageKey": "the_shining.jpg", + "category": "Fiction", + "publisher": "Doubleday", + "author": "Stephen King", + "genres": ["Horror", "Thriller"] + }, + { + "title": "Pride and Prejudice", + "isbn": "9780141439518", + "description": "A romantic novel of manners.", + "releaseDate": "1813-01-28", + "price": 12.99, + "imageKey": "pride_and_prejudice.jpg", + "category": "Fiction", + "publisher": "Penguin Books", + "author": "Jane Austen", + "genres": ["Romance", "Classic"] + }, + { + "title": "The Great Gatsby", + "isbn": "9780743273565", + "description": "The story of the mysteriously wealthy Jay Gatsby.", + "releaseDate": "1925-04-10", + "price": 10.99, + "imageKey": "great_gatsby.jpg", + "category": "Fiction", + "publisher": "Scribner", + "author": "F. Scott Fitzgerald", + "genres": ["Classic", "Romance"] + }, + { + "title": "The Hobbit", + "isbn": "9780547928227", + "description": "A timeless classic of all-age fantasy.", + "releaseDate": "1937-09-21", + "price": 15.00, + "imageKey": "the_hobbit.jpg", + "category": "Fiction", + "publisher": "George Allen & Unwin", + "author": "J.R.R. Tolkien", + "genres": ["Fantasy", "Adventure"] + }, + { + "title": "To Kill a Mockingbird", + "isbn": "9780061120084", + "description": "A novel about the serious issues of rape and racial inequality.", + "releaseDate": "1960-07-11", + "price": 11.99, + "imageKey": "mockingbird.jpg", + "category": "Fiction", + "publisher": "J. B. Lippincott & Co.", + "author": "Harper Lee", + "genres": ["Classic", "Thriller"] + }, + { + "title": "Dune", + "isbn": "9780441172719", + "description": "Set on the desert planet Arrakis.", + "releaseDate": "1965-08-01", + "price": 19.99, + "imageKey": "dune.jpg", + "category": "Fiction", + "publisher": "Chilton Books", + "author": "Frank Herbert", + "genres": ["Science Fiction", "Adventure"] + }, + { + "title": "The Adventures of Sherlock Holmes", + "isbn": "9780140439076", + "description": "A collection of twelve short stories.", + "releaseDate": "1892-10-14", + "price": 9.99, + "imageKey": "sherlock.jpg", + "category": "Fiction", + "publisher": "Penguin Books", + "author": "Arthur Conan Doyle", + "genres": ["Mystery", "Classic"] + }, + { + "title": "The Catcher in the Rye", + "isbn": "9780316769488", + "description": "A story about adolescent alienation.", + "releaseDate": "1951-07-16", + "price": 13.50, + "imageKey": "catcher_rye.jpg", + "category": "Fiction", + "publisher": "Little, Brown and Company", + "author": "J.D. Salinger", + "genres": ["Classic"] + }, + { + "title": "Sapiens: A Brief History of Humankind", + "isbn": "9780062316097", + "description": "The history of humankind from the Stone Age to the twenty-first century.", + "releaseDate": "2011-01-01", + "price": 22.00, + "imageKey": "sapiens.jpg", + "category": "Non-Fiction", + "publisher": "HarperCollins", + "author": "Yuval Noah Harari", + "genres": ["Education", "Psychology"] + }, + { + "title": "Atomic Habits", + "isbn": "9780735211292", + "description": "An easy & proven way to build good habits & break bad ones.", + "releaseDate": "2018-10-16", + "price": 21.99, + "imageKey": "atomic_habits.jpg", + "category": "Non-Fiction", + "publisher": "Penguin Books", + "author": "James Clear", + "genres": ["Self-Help", "Psychology"] + }, + { + "title": "Clean Code", + "isbn": "9780132350884", + "description": "A Handbook of Agile Software Craftsmanship.", + "releaseDate": "2008-08-01", + "price": 45.00, + "imageKey": "clean_code.jpg", + "category": "Technology", + "publisher": "Prentice Hall", + "author": "Robert C. Martin", + "genres": ["Education", "Technical"] + }, + { + "title": "The Da Vinci Code", + "isbn": "9780307474278", + "description": "A mystery detective novel.", + "releaseDate": "2003-03-18", + "price": 16.99, + "imageKey": "da_vinci_code.jpg", + "category": "Fiction", + "publisher": "Doubleday", + "author": "Dan Brown", + "genres": ["Thriller", "Mystery"] + }, + { + "title": "It", + "isbn": "9781501142970", + "description": "The story of seven children terrorized by an evil entity.", + "releaseDate": "1986-09-15", + "price": 19.99, + "imageKey": "it.jpg", + "category": "Fiction", + "publisher": "Penguin Books", + "author": "Stephen King", + "genres": ["Horror"] + }, + { + "title": "A Game of Thrones", + "isbn": "9780553103540", + "description": "The first book in A Song of Ice and Fire.", + "releaseDate": "1996-08-01", + "price": 25.00, + "imageKey": "game_of_thrones.jpg", + "category": "Fiction", + "publisher": "Bantam Books", + "author": "George R.R. Martin", + "genres": ["Fantasy", "Adventure"] + }, + { + "title": "Murder on the Orient Express", + "isbn": "9780062073501", + "description": "A detective novel featuring Hercule Poirot.", + "releaseDate": "1934-01-01", + "price": 12.99, + "imageKey": "orient_express.jpg", + "category": "Fiction", + "publisher": "HarperCollins", + "author": "Agatha Christie", + "genres": ["Mystery", "Classic"] + }, + { + "title": "The Alchemist", + "isbn": "9780062315007", + "description": "A novel about following your dream.", + "releaseDate": "1988-01-01", + "price": 16.50, + "imageKey": "alchemist.jpg", + "category": "Fiction", + "publisher": "HarperCollins", + "author": "Paulo Coelho", + "genres": ["Adventure", "Self-Help"] + }, + { + "title": "Fahrenheit 451", + "isbn": "9781451673319", + "description": "A future American society where books are outlawed.", + "releaseDate": "1953-10-19", + "price": 15.99, + "imageKey": "fahrenheit_451.jpg", + "category": "Fiction", + "publisher": "Simon & Schuster", + "author": "Ray Bradbury", + "genres": ["Dystopian", "Science Fiction"] + }, + { + "title": "Gone Girl", + "isbn": "9780307588371", + "description": "A thriller about a woman who disappears on her fifth wedding anniversary.", + "releaseDate": "2012-06-05", + "price": 14.00, + "imageKey": "gone_girl.jpg", + "category": "Fiction", + "publisher": "Crown Publishing Group", + "author": "Gillian Flynn", + "genres": ["Thriller", "Mystery"] + }, + { + "title": "Thinking, Fast and Slow", + "isbn": "9780374275631", + "description": "The two systems that drive the way we think.", + "releaseDate": "2011-10-25", + "price": 20.00, + "imageKey": "thinking_fast.jpg", + "category": "Non-Fiction", + "publisher": "Farrar, Straus and Giroux", + "author": "Daniel Kahneman", + "genres": ["Psychology", "Education"] + }, + { + "title": "Steve Jobs", + "isbn": "9781451648539", + "description": "The biography of the co-founder of Apple Inc.", + "releaseDate": "2011-10-24", + "price": 30.00, + "imageKey": "steve_jobs.jpg", + "category": "Biography", + "publisher": "Simon & Schuster", + "author": "Walter Isaacson", + "genres": ["Education", "Technical"] + }, + { + "title": "The Lord of the Rings", + "isbn": "9780618640157", + "description": "High fantasy novel.", + "releaseDate": "1954-07-29", + "price": 35.00, + "imageKey": "lotr.jpg", + "category": "Fiction", + "publisher": "George Allen & Unwin", + "author": "J.R.R. Tolkien", + "genres": ["Fantasy", "Adventure"] + }, + { + "title": "Brave New World", + "isbn": "9780060850524", + "description": "A dystopian social science fiction novel.", + "releaseDate": "1932-01-01", + "price": 14.50, + "imageKey": "brave_new_world.jpg", + "category": "Fiction", + "publisher": "Chatto & Windus", + "author": "Aldous Huxley", + "genres": ["Dystopian", "Science Fiction"] + }, + { + "title": "The Silent Patient", + "isbn": "9781250301697", + "description": "A psychological thriller about a woman who shoots her husband.", + "releaseDate": "2019-02-05", + "price": 17.99, + "imageKey": "silent_patient.jpg", + "category": "Fiction", + "publisher": "Celadon Books", + "author": "Alex Michaelides", + "genres": ["Thriller", "Mystery"] + } +] \ No newline at end of file diff --git a/data/seeding/categories.json b/data/seeding/categories.json new file mode 100644 index 0000000..c2ca0f1 --- /dev/null +++ b/data/seeding/categories.json @@ -0,0 +1,18 @@ +[ + { + "name": "Fiction", + "description": "Narrative literature created from the imagination." + }, + { + "name": "Non-Fiction", + "description": "Prose writing that is based on facts, real events, and real people." + }, + { + "name": "Technology", + "description": "Books about programming, engineering and tech industry." + }, + { + "name": "Biography", + "description": "A detailed description of a person's life." + } +] \ No newline at end of file diff --git a/data/seeding/genres.json b/data/seeding/genres.json new file mode 100644 index 0000000..cb60890 --- /dev/null +++ b/data/seeding/genres.json @@ -0,0 +1,14 @@ +[ + { "name": "Dystopian", "description": "Societies characterized by human misery." }, + { "name": "Fantasy", "description": "Stories with magic and supernatural elements." }, + { "name": "Horror", "description": "Fiction intended to scare or disgust." }, + { "name": "Romance", "description": "Focus on relationship and romantic love." }, + { "name": "Classic", "description": "Books of high literary merit that have stood the test of time." }, + { "name": "Science Fiction", "description": "Speculative fiction based on future science." }, + { "name": "Mystery", "description": "Stories involving a crime or puzzle to solve." }, + { "name": "Thriller", "description": "Suspenseful stories with high stakes." }, + { "name": "Adventure", "description": "Stories featuring exciting and dangerous journeys." }, + { "name": "Self-Help", "description": "Books written to instruct on solving personal problems." }, + { "name": "Psychology", "description": "Study of mind and behavior." }, + { "name": "Education", "description": "Textbooks and learning materials." } +] \ No newline at end of file diff --git a/data/seeding/publishers.json b/data/seeding/publishers.json new file mode 100644 index 0000000..1081372 --- /dev/null +++ b/data/seeding/publishers.json @@ -0,0 +1,14 @@ +[ + { "name": "Penguin Books", "address": "London, UK" }, + { "name": "Bloomsbury", "address": "London, UK" }, + { "name": "Scribner", "address": "New York, USA" }, + { "name": "HarperCollins", "address": "New York, USA" }, + { "name": "Doubleday", "address": "New York, USA" }, + { "name": "George Allen & Unwin", "address": "Sydney, Australia" }, + { "name": "J. B. Lippincott & Co.", "address": "Philadelphia, USA" }, + { "name": "Chilton Books", "address": "Boston, USA" }, + { "name": "Little, Brown and Company", "address": "Boston, USA" }, + { "name": "Random House", "address": "New York, USA" }, + { "name": "Prentice Hall", "address": "New Jersey, USA" }, + { "name": "Celadon Books", "address": "New York, USA" } +] \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 4d19981..47ed6e2 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -10,7 +10,7 @@ services: ports: - "27018:27017" volumes: - - ./docker/mongodb/data:/data/db + - mongodb_data:/data/db healthcheck: test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet networks: @@ -23,6 +23,8 @@ services: container_name: book-service ports: - "8080:8080" + volumes: + - ./data:/app/data depends_on: mysql: condition: service_healthy @@ -80,4 +82,7 @@ services: volumes: - ./infrastructure/prometheus/prometheus-prod.yml:/etc/prometheus/prometheus.yml networks: - - e-library-network \ No newline at end of file + - e-library-network + +volumes: + mongodb_data: \ No newline at end of file