Реализовал многомодульный crud

This commit is contained in:
Struchkov Mark 2022-10-22 18:09:06 +03:00
parent 5a568acaed
commit 9ba51e0c64
49 changed files with 1678 additions and 70 deletions

93
filmorate-app/pom.xml Normal file
View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-bom</artifactId>
<version>${filmorate.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<filmorate.version>0.0.1-SNAPSHOT</filmorate.version>
</properties>
<dependencies>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-core</artifactId>
</dependency>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-data-jpa</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>dev.struchkov.filmorate</groupId>-->
<!-- <artifactId>filmorate-data-local</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
</dependencies>
<build>
<finalName>filmorate</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,5 @@
spring:
application:
name: Filmorate Local
liquibase:
contexts: local

View File

@ -0,0 +1,10 @@
spring:
application:
name: Filmorate
liquibase:
change-log: db/changelog/changelog-master.xml
datasource:
driver-class-name: org.postgresql.Driver
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.6.xsd">
<include file="v.1.0.0/changelog.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.6.xsd">
<changeSet id="2022-10-22-create-table-person" author="uPageg">
<createTable tableName="person">
<column name="id" type="bigint" autoIncrement="true">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="name" type="varchar(100)"/>
<column name="email" type="varchar(100)"/>
<column name="login" type="varchar(100)">
<constraints nullable="true" unique="true"/>
</column>
<column name="birthday" type="date"/>
</createTable>
</changeSet>
<changeSet id="2022-10-22-create-table-film" author="uPagge">
<createTable tableName="film" remarks="Фильмы">
<column name="id" type="bigint" autoIncrement="true">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="name" type="varchar(100)">
<constraints nullable="false"/>
</column>
<column name="description" type="text"/>
<column name="date_release" type="date"/>
<column name="duration_in_minutes" type="int"/>
<column name="date_created" type="datetime">
<constraints nullable="false"/>
</column>
<column name="date_updated" type="datetime"/>
<column name="person_owner_id" type="bigint">
<constraints nullable="false" foreignKeyName="fk_film_person_owner_id_person_id"
references="person(id)" deleteCascade="true"/>
</column>
</createTable>
<createIndex tableName="film" indexName="i_film_person_owner_id">
<column name="person_owner_id"/>
</createIndex>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.6.xsd">
<changeSet id="2022-10-22-insert-test-data" author="uPagge">
<insert tableName="person">
<column name="name" value="Иванов Иван"/>
<column name="email" value="ivanov@ya.ru"/>
<column name="login" value="ivanov"/>
<column name="birthday" value="1990-12-20"/>
</insert>
<insert tableName="person">
<column name="name" value="Петров Петр"/>
<column name="email" value="petrov@ya.ru"/>
<column name="login" value="petrov"/>
<column name="birthday" value="1980-06-12"/>
</insert>
<insert tableName="film">
<column name="name" value="Фильм 1"/>
<column name="description" value="Простой фильм о почтальоне"/>
<column name="date_release" value="2000-10-11"/>
<column name="duration_in_minutes" value="90"/>
<column name="date_created" value="2022-10-22T12:12:12"/>
<column name="person_owner_id" value="1"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.6.xsd">
<changeSet id="2022-10-22-tag-1-0-0" author="uPagge">
<tagDatabase tag="v.1.0.0."/>
</changeSet>
<include file="2022-10-22-create-main-tables.xml" relativeToChangelogFile="true"/>
<include file="2022-10-22-insert-test-data.xml" context="local" relativeToChangelogFile="true"/>
</databaseChangeLog>

84
filmorate-bom/pom.xml Normal file
View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-bom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<filmorate.version>0.0.1-SNAPSHOT</filmorate.version>
<filmorate.domain.version>${filmorate.version}</filmorate.domain.version>
<filmorate.context.version>${filmorate.version}</filmorate.context.version>
<filmorate.core.version>${filmorate.version}</filmorate.core.version>
<filmorate.data.jpa.version>${filmorate.version}</filmorate.data.jpa.version>
<filmorate.data.local.version>${filmorate.version}</filmorate.data.local.version>
<filmorate.web.version>${filmorate.version}</filmorate.web.version>
<spring.starter.parent.version>2.7.5</spring.starter.parent.version>
<mapstruct.version>1.5.2.Final</mapstruct.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.starter.parent.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-domain</artifactId>
<version>${filmorate.domain.version}</version>
</dependency>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-context</artifactId>
<version>${filmorate.context.version}</version>
</dependency>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-core</artifactId>
<version>${filmorate.core.version}</version>
</dependency>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-data-local</artifactId>
<version>${filmorate.data.local.version}</version>
</dependency>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-data-jpa</artifactId>
<version>${filmorate.data.jpa.version}</version>
</dependency>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-web</artifactId>
<version>${filmorate.web.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

44
filmorate-context/pom.xml Normal file
View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>filmorate-context</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-domain</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,19 @@
package dev.struchkov.filmorate.context;
import lombok.experimental.UtilityClass;
@UtilityClass
public final class Message {
@UtilityClass
public static class NotFound {
public static final String FILM = "Фильм не найден. Идентификатор: {0}";
public static final String PERSON = "Пользователь не найден. Идентификатор: {0}";
}
@UtilityClass
public static class Error {
}
}

View File

@ -0,0 +1,15 @@
package dev.struchkov.filmorate.context.exception;
import java.text.MessageFormat;
public abstract class FilmorateException extends RuntimeException {
protected FilmorateException(String message) {
super(message);
}
protected FilmorateException(String message, Object... args) {
super(MessageFormat.format(message, args));
}
}

View File

@ -0,0 +1,15 @@
package dev.struchkov.filmorate.context.exception;
import java.util.function.Supplier;
public class NotFoundException extends FilmorateException{
public NotFoundException(String message, Object... args) {
super(message, args);
}
public static Supplier<NotFoundException> notFoundException(String message, Object... args) {
return () -> new NotFoundException(message, args);
}
}

View File

@ -0,0 +1,20 @@
package dev.struchkov.filmorate.context.repository;
import dev.strichkov.filmorate.domain.Film;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import lombok.NonNull;
import java.util.Optional;
public interface FilmRepository {
Film save(@NonNull Film film);
Optional<Film> findById(@NonNull Long filmId);
Sheet<Film> findAll(@NonNull Pagination pagination);
void deleteById(@NonNull Long filmId);
}

View File

@ -0,0 +1,20 @@
package dev.struchkov.filmorate.context.repository;
import dev.strichkov.filmorate.domain.Person;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import lombok.NonNull;
import java.util.Optional;
public interface PersonRepository {
Person save(@NonNull Person person);
Optional<Person> findById(@NonNull Long personId);
void deleteById(@NonNull Long personId);
Sheet<Person> findByAll(@NonNull Pagination pagination);
}

View File

@ -0,0 +1,24 @@
package dev.struchkov.filmorate.context.service;
import dev.strichkov.filmorate.domain.Film;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import lombok.NonNull;
import java.util.Optional;
public interface FilmService {
Film create(@NonNull Film film);
Film update(@NonNull Film film);
void deleteById(@NonNull Long filmId);
Optional<Film> getById(@NonNull Long filmId);
Film getByIdOrThrow(@NonNull Long filmId);
Sheet<Film> getAll(@NonNull Pagination pagination);
}

View File

@ -0,0 +1,24 @@
package dev.struchkov.filmorate.context.service;
import dev.strichkov.filmorate.domain.Person;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import lombok.NonNull;
import java.util.Optional;
public interface PersonService {
Person create(@NonNull Person person);
Person update(@NonNull Person person);
void deleteById(@NonNull Long personId);
Optional<Person> getById(@NonNull Long personId);
Person getByIdOrThrow(@NonNull Long personId);
Sheet<Person> getAll(@NonNull Pagination pagination);
}

53
filmorate-core/pom.xml Normal file
View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>filmorate-core</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,69 @@
package dev.struchkov.filmorate.core.service;
import dev.strichkov.filmorate.domain.Film;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import dev.struchkov.filmorate.context.Message;
import dev.struchkov.filmorate.context.repository.FilmRepository;
import dev.struchkov.filmorate.context.service.FilmService;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Optional;
import static dev.struchkov.filmorate.context.exception.NotFoundException.notFoundException;
@Service
@RequiredArgsConstructor
public class FilmServiceImpl implements FilmService {
private final FilmRepository repository;
@Override
@Transactional
public Film create(@NonNull Film film) {
film.setDateCreated(film.getDateCreated());
return repository.save(film);
}
@Override
@Transactional
public Film update(@NonNull Film newFilm) {
final Film oldFilm = repository.findById(newFilm.getId())
.orElseThrow(notFoundException(Message.NotFound.FILM, newFilm.getId()));
oldFilm.setName(newFilm.getName());
oldFilm.setDurationInMinutes(newFilm.getDurationInMinutes());
oldFilm.setDateRelease(newFilm.getDateRelease());
oldFilm.setDescription(newFilm.getDescription());
oldFilm.setDateUpdated(LocalDateTime.now());
return oldFilm;
}
@Override
public void deleteById(@NonNull Long filmId) {
repository.deleteById(filmId);
}
@Override
@Transactional(readOnly = true)
public Optional<Film> getById(@NonNull Long filmId) {
return repository.findById(filmId);
}
@Override
@Transactional(readOnly = true)
public Film getByIdOrThrow(@NonNull Long filmId) {
return repository.findById(filmId)
.orElseThrow(notFoundException(Message.NotFound.FILM, filmId));
}
@Override
@Transactional(readOnly = true)
public Sheet<Film> getAll(@NonNull Pagination pagination) {
return repository.findAll(pagination);
}
}

View File

@ -0,0 +1,65 @@
package dev.struchkov.filmorate.core.service;
import dev.strichkov.filmorate.domain.Person;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import dev.struchkov.filmorate.context.Message;
import dev.struchkov.filmorate.context.repository.PersonRepository;
import dev.struchkov.filmorate.context.service.PersonService;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
import static dev.struchkov.filmorate.context.exception.NotFoundException.notFoundException;
@Service
@RequiredArgsConstructor
public class PersonServiceImpl implements PersonService {
private final PersonRepository repository;
@Override
@Transactional
public Person create(@NonNull Person person) {
return repository.save(person);
}
@Override
@Transactional
public Person update(@NonNull Person newPerson) {
final Person oldPerson = repository.findById(newPerson.getId())
.orElseThrow(notFoundException(Message.NotFound.PERSON, newPerson.getId()));
oldPerson.setName(newPerson.getName());
oldPerson.setEmail(newPerson.getEmail());
oldPerson.setBirthday(newPerson.getBirthday());
return oldPerson;
}
@Override
@Transactional
public void deleteById(@NonNull Long personId) {
repository.deleteById(personId);
}
@Override
@Transactional(readOnly = true)
public Optional<Person> getById(@NonNull Long personId) {
return repository.findById(personId);
}
@Override
@Transactional(readOnly = true)
public Person getByIdOrThrow(@NonNull Long personId) {
return repository.findById(personId)
.orElseThrow(notFoundException(Message.NotFound.PERSON, personId));
}
@Override
@Transactional(readOnly = true)
public Sheet<Person> getAll(@NonNull Pagination pagination) {
return repository.findByAll(pagination);
}
}

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>filmorate-data-jpa</artifactId>
<dependencies>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,22 @@
package dev.struchkov.filmorate.data.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
@Getter
@Setter
@MappedSuperclass
public abstract class BaseEntity {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
}

View File

@ -0,0 +1,38 @@
package dev.struchkov.filmorate.data.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.time.LocalDateTime;
@Entity
@Getter
@Setter
@Table(name = "film")
public class FilmEntity extends BaseEntity {
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "date_release")
private LocalDateTime dateRelease;
@Column(name = "duration_in_minutes")
private Integer durationInMinutes;
@Column(name = "date_created")
private LocalDateTime dateCreated;
@Column(name = "date_updated")
private LocalDateTime dateUpdated;
@Column(name = "person_owner_id")
private Long ownerId;
}

View File

@ -0,0 +1,29 @@
package dev.struchkov.filmorate.data.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.time.LocalDateTime;
@Entity
@Getter
@Setter
@Table(name = "person")
public class PersonEntity extends BaseEntity {
@Column(name = "name")
private String name;
@Column(name = "email")
private String email;
@Column(name = "login")
private String login;
@Column(name = "birthday")
private LocalDateTime birthday;
}

View File

@ -0,0 +1,7 @@
package dev.struchkov.filmorate.data.jpa;
import dev.struchkov.filmorate.data.entity.FilmEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface FilmJpaRepository extends JpaRepository<FilmEntity, Long> {
}

View File

@ -0,0 +1,7 @@
package dev.struchkov.filmorate.data.jpa;
import dev.struchkov.filmorate.data.entity.PersonEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PersonJpaRepository extends JpaRepository<PersonEntity, Long> {
}

View File

@ -0,0 +1,14 @@
package dev.struchkov.filmorate.data.mapper;
import dev.strichkov.filmorate.domain.Film;
import dev.struchkov.filmorate.data.entity.FilmEntity;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public interface FilmEntityMapper {
FilmEntity toEntity(Film film);
Film toDomain(FilmEntity film);
}

View File

@ -0,0 +1,14 @@
package dev.struchkov.filmorate.data.mapper;
import dev.strichkov.filmorate.domain.Person;
import dev.struchkov.filmorate.data.entity.PersonEntity;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public interface PersonEntityMapper {
PersonEntity toEntity(Person person);
Person toDomain(PersonEntity entity);
}

View File

@ -0,0 +1,56 @@
package dev.struchkov.filmorate.data.repository;
import dev.strichkov.filmorate.domain.Film;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import dev.struchkov.filmorate.context.repository.FilmRepository;
import dev.struchkov.filmorate.data.jpa.FilmJpaRepository;
import dev.struchkov.filmorate.data.mapper.FilmEntityMapper;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
@RequiredArgsConstructor
public class FilmRepositoryImpl implements FilmRepository {
private final FilmJpaRepository jpaRepository;
private final FilmEntityMapper filmMapper;
@Override
public Film save(@NonNull Film film) {
return filmMapper.toDomain(
jpaRepository.save(filmMapper.toEntity(film))
);
}
@Override
public Optional<Film> findById(@NonNull Long filmId) {
return jpaRepository.findById(filmId)
.map(filmMapper::toDomain);
}
@Override
public Sheet<Film> findAll(@NonNull Pagination pagination) {
final PageRequest pageable = PageRequest.of(pagination.getPageNumber(), pagination.getPageSize());
final Page<Film> page = jpaRepository.findAll(pageable)
.map(filmMapper::toDomain);
return Sheet.<Film>builder()
.totalElements(page.getTotalElements())
.totalPage(page.getTotalPages())
.pageNumber(pagination.getPageNumber())
.pageSize(pagination.getPageSize())
.content(page.getContent())
.build();
}
@Override
public void deleteById(@NonNull Long filmId) {
jpaRepository.deleteById(filmId);
}
}

View File

@ -0,0 +1,58 @@
package dev.struchkov.filmorate.data.repository;
import dev.strichkov.filmorate.domain.Person;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import dev.struchkov.filmorate.context.repository.PersonRepository;
import dev.struchkov.filmorate.data.jpa.PersonJpaRepository;
import dev.struchkov.filmorate.data.mapper.PersonEntityMapper;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
@RequiredArgsConstructor
public class PersonRepositoryImpl implements PersonRepository {
private final PersonJpaRepository jpaRepository;
private final PersonEntityMapper personMapper;
@Override
public Person save(@NonNull Person person) {
return personMapper.toDomain(
jpaRepository.save(
personMapper.toEntity(person)
)
);
}
@Override
public Optional<Person> findById(@NonNull Long personId) {
return jpaRepository.findById(personId)
.map(personMapper::toDomain);
}
@Override
public void deleteById(@NonNull Long personId) {
jpaRepository.deleteById(personId);
}
@Override
public Sheet<Person> findByAll(@NonNull Pagination pagination) {
final PageRequest pageable = PageRequest.of(pagination.getPageNumber(), pagination.getPageSize());
final Page<Person> page = jpaRepository.findAll(pageable)
.map(personMapper::toDomain);
return Sheet.<Person>builder()
.totalPage(page.getTotalPages())
.totalElements(page.getTotalElements())
.pageSize(page.getSize())
.pageNumber(page.getNumber())
.content(page.getContent())
.build();
}
}

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>filmorate-data-local</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-context</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,42 @@
package dev.struchkov.filmorate.data.repository;
import dev.strichkov.filmorate.domain.Film;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import dev.struchkov.filmorate.context.repository.FilmRepository;
import lombok.NonNull;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@Repository
public class FilmLocalRepository implements FilmRepository {
private final Map<Long, Film> storage = new HashMap<>();
private long gen = 0;
@Override
public Film save(@NonNull Film film) {
film.setId(gen++);
storage.put(film.getId(), film);
return film;
}
@Override
public Optional<Film> findById(@NonNull Long filmId) {
return Optional.ofNullable(storage.get(filmId));
}
@Override
public Sheet<Film> findAll(@NonNull Pagination pagination) {
throw new UnsupportedOperationException("Не работает :(");
}
@Override
public void deleteById(@NonNull Long filmId) {
storage.remove(filmId);
}
}

View File

@ -0,0 +1,42 @@
package dev.struchkov.filmorate.data.repository;
import dev.strichkov.filmorate.domain.Person;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import dev.struchkov.filmorate.context.repository.PersonRepository;
import lombok.NonNull;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@Repository
public class PersonLocalRepository implements PersonRepository {
private final Map<Long, Person> storage = new HashMap<>();
private long gen = 0;
@Override
public Person save(@NonNull Person person) {
person.setId(gen++);
storage.put(person.getId(), person);
return person;
}
@Override
public Optional<Person> findById(@NonNull Long personId) {
return Optional.ofNullable(storage.get(personId));
}
@Override
public void deleteById(@NonNull Long personId) {
storage.remove(personId);
}
@Override
public Sheet<Person> findByAll(@NonNull Pagination pagination) {
throw new UnsupportedOperationException("Не работает");
}
}

37
filmorate-domain/pom.xml Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>filmorate-domain</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,29 @@
package dev.strichkov.filmorate.domain;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Getter
@Setter
public class Film {
private Long id;
private String name;
private String description;
private LocalDate dateRelease;
private Integer durationInMinutes;
private LocalDateTime dateCreated;
private LocalDateTime dateUpdated;
private Long ownerId;
}

View File

@ -0,0 +1,22 @@
package dev.strichkov.filmorate.domain;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
@Getter
@Setter
public class Person {
private Long id;
private String name;
private String email;
private String login;
private LocalDateTime birthday;
}

View File

@ -0,0 +1,13 @@
package dev.strichkov.filmorate.domain.page;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public class Pagination {
private Integer pageNumber;
private Integer pageSize;
}

View File

@ -0,0 +1,29 @@
package dev.strichkov.filmorate.domain.page;
import lombok.Builder;
import lombok.Getter;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
@Getter
@Builder
public class Sheet<T> {
private List<T> content;
private Long totalElements;
private Integer totalPage;
private Integer pageSize;
private Integer pageNumber;
public <D> Sheet<D> map(Function<T, D> mapping) {
return Sheet.<D>builder()
.totalElements(totalElements)
.totalPage(totalPage)
.pageNumber(pageNumber)
.pageSize(pageSize)
.content(content.stream().map(mapping).collect(Collectors.toList()) )
.build();
}
}

63
filmorate-web/pom.xml Normal file
View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>filmorate-web</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,82 @@
package dev.struchkov.filmorate.web.controller;
import dev.strichkov.filmorate.domain.Film;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import dev.struchkov.filmorate.context.service.FilmService;
import dev.struchkov.filmorate.web.dto.FilmDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.core.convert.ConversionService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
@RestController
@RequiredArgsConstructor
@RequestMapping("api/film")
@Tag(name = "Фильмы", description = "Эндпойнты для работы с фильмами")
public class FilmController {
private final FilmService filmService;
private final ConversionService conversionService;
@Operation(summary = "Добавление нового фильма")
@PostMapping(produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
public ResponseEntity<FilmDto> create(@RequestBody FilmDto filmDto) {
return ResponseEntity.ok(
conversionService.convert(
filmService.create(conversionService.convert(filmDto, Film.class)),
FilmDto.class
)
);
}
@Operation(summary = "Обновление фильма")
@PutMapping(produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
public ResponseEntity<FilmDto> update(@RequestBody FilmDto filmDto) {
return ResponseEntity.ok(
conversionService.convert(
filmService.update(conversionService.convert(filmDto, Film.class)),
FilmDto.class
)
);
}
@Operation(summary = "Получение фильма по идентификатору")
@PutMapping(value = "{filmId}", produces = APPLICATION_JSON_VALUE)
public ResponseEntity<FilmDto> getById(@PathVariable Long filmId) {
return ResponseEntity.ok(
conversionService.convert(
filmService.getByIdOrThrow(filmId),
FilmDto.class
)
);
}
@Operation(summary = "Получение всех фильмов с пагинацией")
@GetMapping(produces = APPLICATION_JSON_VALUE)
public ResponseEntity<Sheet<FilmDto>> getAllByFilter(
@Parameter(description = "Номер страницы", required = true) @Min(0) @RequestParam Integer pageNum,
@Parameter(description = "Количество элементов", required = true) @Min(1) @Max(100) @RequestParam Integer pageSize
) {
return ResponseEntity.ok(
filmService.getAll(new Pagination(pageSize, pageSize))
.map(film -> conversionService.convert(film, FilmDto.class))
);
}
}

View File

@ -0,0 +1,82 @@
package dev.struchkov.filmorate.web.controller;
import dev.strichkov.filmorate.domain.page.Pagination;
import dev.strichkov.filmorate.domain.page.Sheet;
import dev.struchkov.filmorate.context.service.PersonService;
import dev.struchkov.filmorate.web.dto.PersonDto;
import dev.struchkov.filmorate.web.mapper.PersonMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
@RestController
@RequiredArgsConstructor
@RequestMapping("api/person")
@Tag(name = "Пользователи системы", description = "Эндпойнты для работы с пользователями системы")
public class PersonController {
private final PersonService personService;
private final PersonMapper personMapper;
@Operation(summary = "Регистрация нового пользователя")
@PostMapping(produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
public ResponseEntity<PersonDto> create(@RequestBody PersonDto personDto) {
return ResponseEntity.ok(
personMapper.toDto(
personService.create(
personMapper.toDomain(personDto)
)
)
);
}
@Operation(summary = "Обновление пользователя")
@PutMapping(produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
public ResponseEntity<PersonDto> update(@RequestBody PersonDto personDto) {
return ResponseEntity.ok(
personMapper.toDto(
personService.update(
personMapper.toDomain(personDto)
)
)
);
}
@Operation(summary = "Получение пользователя по идентификатору")
@PutMapping(value = "{personId}", produces = APPLICATION_JSON_VALUE)
public ResponseEntity<PersonDto> getById(@PathVariable Long personId) {
return ResponseEntity.ok(
personMapper.toDto(
personService.getByIdOrThrow(personId)
)
);
}
@Operation(summary = "Получение всех пользователей с пагинацией")
@GetMapping(produces = APPLICATION_JSON_VALUE)
public ResponseEntity<Sheet<PersonDto>> getAllByFilter(
@Parameter(description = "Номер страницы", required = true) @Min(0) @RequestParam Integer pageNum,
@Parameter(description = "Количество элементов", required = true) @Min(1) @Max(100) @RequestParam Integer pageSize
) {
return ResponseEntity.ok(
personService.getAll(new Pagination(pageNum, pageSize))
.map(personMapper::toDto)
);
}
}

View File

@ -0,0 +1,21 @@
package dev.struchkov.filmorate.web.converter;
import dev.strichkov.filmorate.domain.Film;
import dev.struchkov.filmorate.web.dto.FilmDto;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@Component
public class FilmToDtoConvert implements Converter<Film, FilmDto> {
@Override
public FilmDto convert(Film source) {
final FilmDto filmDto = new FilmDto();
filmDto.setId(source.getId());
filmDto.setName(source.getName());
filmDto.setDurationInMinutes(source.getDurationInMinutes());
filmDto.setDateRelease(source.getDateRelease());
filmDto.setDescription(source.getDescription());
return filmDto;
}
}

View File

@ -0,0 +1,22 @@
package dev.struchkov.filmorate.web.converter;
import dev.strichkov.filmorate.domain.Film;
import dev.struchkov.filmorate.web.dto.FilmDto;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@Component
public class FilmToEntityConvert implements Converter<FilmDto, Film> {
@Override
public Film convert(FilmDto source) {
final Film film = new Film();
film.setId(source.getId());
film.setName(source.getName());
film.setDescription(source.getDescription());
film.setDateRelease(source.getDateRelease());
film.setDurationInMinutes(source.getDurationInMinutes());
return film;
}
}

View File

@ -0,0 +1,39 @@
package dev.struchkov.filmorate.web.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Getter
@Setter
@Schema(description = "Фильм")
public class FilmDto {
@Schema(name = "Идентификатор")
private Long id;
@Schema(name = "Название")
private String name;
@Schema(name = "Описание")
private String description;
@Schema(name = "Дата релиза")
private LocalDate dateRelease;
@Schema(name = "Продолжительность")
private Integer durationInMinutes;
@Schema(name = "Дата Создания")
private LocalDateTime dateCreated;
@Schema(name = "Дата обновления")
private LocalDateTime dateUpdated;
@Schema(name = "Владелец фильма")
private Long ownerId;
}

View File

@ -0,0 +1,29 @@
package dev.struchkov.filmorate.web.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
@Getter
@Setter
@Schema(description = "Пользователь системы")
public class PersonDto {
@Schema(description = "Идентификатор")
private Long id;
@Schema(description = "Имя")
private String name;
@Schema(description = "Почта")
private String email;
@Schema(description = "Логин")
private String login;
@Schema(description = "День рождения")
private LocalDateTime birthday;
}

View File

@ -0,0 +1,14 @@
package dev.struchkov.filmorate.web.mapper;
import dev.strichkov.filmorate.domain.Person;
import dev.struchkov.filmorate.web.dto.PersonDto;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public interface PersonMapper {
PersonDto toDto(Person person);
Person toDomain(PersonDto personDto);
}

161
pom.xml
View File

@ -2,77 +2,126 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>dev.struchkov.example</groupId>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>filmorate</name>
<description>filmorate</description>
<packaging>pom</packaging>
<modules>
<module>filmorate-domain</module>
<module>filmorate-context</module>
<module>filmorate-core</module>
<module>filmorate-data-jpa</module>
<module>filmorate-data-local</module>
<module>filmorate-web</module>
</modules>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<plugin.maven.compiler.version>3.10.1</plugin.maven.compiler.version>
<plugin.maven.source.version>3.2.1</plugin.maven.source.version>
<plugin.maven.javadoc.version>3.4.1</plugin.maven.javadoc.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>dev.struchkov.filmorate</groupId>
<artifactId>filmorate-bom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${plugin.maven.compiler.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${plugin.maven.source.version}</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${plugin.maven.javadoc.version}</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
<developers>
<developer>
<id>uPagge</id>
<name>Struchkov Mark</name>
<email>mark@struchkov.dev</email>
<url>https://mark.struchkov.dev</url>
</developer>
</developers>
</project>

View File

@ -1 +0,0 @@

View File

@ -1,13 +0,0 @@
package dev.struchkov.filmorate;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class FilmorateApplicationTests {
@Test
void contextLoads() {
}
}