diff --git a/schedule/pom.xml b/schedule/pom.xml index 3cdb671..7dce915 100644 --- a/schedule/pom.xml +++ b/schedule/pom.xml @@ -31,6 +31,10 @@ 2024.0.0 + + org.springframework.boot + spring-boot-starter-web + org.flywaydb flyway-core @@ -68,6 +72,32 @@ spring-kafka-test test + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.mapstruct + mapstruct + 1.5.5.Final + + + org.mapstruct + mapstruct-processor + 1.5.5.Final + provided + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.7.0 + @@ -92,6 +122,11 @@ org.projectlombok lombok + + org.mapstruct + mapstruct-processor + 1.5.5.Final + diff --git a/schedule/src/main/java/edu/unive/schedule/ScheduleApplication.java b/schedule/src/main/java/edu/unive/schedule/ScheduleApplication.java index 6e21ec8..5a563da 100644 --- a/schedule/src/main/java/edu/unive/schedule/ScheduleApplication.java +++ b/schedule/src/main/java/edu/unive/schedule/ScheduleApplication.java @@ -2,8 +2,10 @@ package edu.unive.schedule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; @SpringBootApplication +@PropertySource("classpath:application.yml") public class ScheduleApplication { public static void main(String[] args) { diff --git a/schedule/src/main/java/edu/unive/schedule/controller/ClassroomApi.java b/schedule/src/main/java/edu/unive/schedule/controller/ClassroomApi.java new file mode 100644 index 0000000..c9c46ee --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/controller/ClassroomApi.java @@ -0,0 +1,14 @@ +package edu.unive.schedule.controller; + +import edu.unive.schedule.domain.Classroom; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RequestMapping("/api/classrooms") +public interface ClassroomApi { + @PostMapping + ResponseEntity createClassroom(@RequestBody Classroom classroomDTO); + + @GetMapping("/{id}") + ResponseEntity getClassroom(@PathVariable Long id); +} diff --git a/schedule/src/main/java/edu/unive/schedule/controller/ClassroomController.java b/schedule/src/main/java/edu/unive/schedule/controller/ClassroomController.java new file mode 100644 index 0000000..e3e76bc --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/controller/ClassroomController.java @@ -0,0 +1,24 @@ +package edu.unive.schedule.controller; + +import edu.unive.schedule.domain.Classroom; +import edu.unive.schedule.service.ClassroomService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class ClassroomController implements ClassroomApi{ + + private final ClassroomService classroomService; + + public ResponseEntity createClassroom(Classroom classroomDTO) { + classroomService.createClassroom(classroomDTO); + return ResponseEntity.ok().build(); + } + + public ResponseEntity getClassroom(Long id) { + var dto = classroomService.getClassroomById(id); + return ResponseEntity.ok(dto); + } +} diff --git a/schedule/src/main/java/edu/unive/schedule/controller/ScheduleApi.java b/schedule/src/main/java/edu/unive/schedule/controller/ScheduleApi.java new file mode 100644 index 0000000..de2b7f3 --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/controller/ScheduleApi.java @@ -0,0 +1,18 @@ +package edu.unive.schedule.controller; + +import edu.unive.schedule.domain.Schedule; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RequestMapping("/api/schedules") +public interface ScheduleApi { + + @PostMapping + ResponseEntity createSchedule(@RequestBody Schedule scheduleDTO); + + @PutMapping("/{id}") + ResponseEntity updateSchedule(@PathVariable Long id, @RequestBody Schedule scheduleDTO); + + @DeleteMapping("/{id}") + ResponseEntity deleteSchedule(@PathVariable Long id); +} diff --git a/schedule/src/main/java/edu/unive/schedule/controller/ScheduleController.java b/schedule/src/main/java/edu/unive/schedule/controller/ScheduleController.java new file mode 100644 index 0000000..ec1ebe6 --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/controller/ScheduleController.java @@ -0,0 +1,33 @@ +package edu.unive.schedule.controller; + +import edu.unive.schedule.domain.Schedule; +import edu.unive.schedule.service.ScheduleService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +public class ScheduleController implements ScheduleApi { + + private final ScheduleService scheduleService; + + @Override + public ResponseEntity createSchedule(Schedule scheduleDTO) { + scheduleService.createSchedule(scheduleDTO); + + return ResponseEntity.ok().build(); + } + + @Override + public ResponseEntity updateSchedule(Long id, Schedule scheduleDTO) { + scheduleService.updateSchedule(id, scheduleDTO); + return ResponseEntity.ok().build(); + } + + @Override + public ResponseEntity deleteSchedule(@PathVariable Long id) { + scheduleService.deleteSchedule(id); + return ResponseEntity.ok().build(); + } +} diff --git a/schedule/src/main/java/edu/unive/schedule/domain/Classroom.java b/schedule/src/main/java/edu/unive/schedule/domain/Classroom.java new file mode 100644 index 0000000..ec76b62 --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/domain/Classroom.java @@ -0,0 +1,12 @@ +package edu.unive.schedule.domain; + + +import edu.unive.schedule.domain.entity.ClassroomType; +import lombok.Data; + +@Data +public class Classroom { + private Long id; + private String name; + private ClassroomType type; +} diff --git a/schedule/src/main/java/edu/unive/schedule/domain/Schedule.java b/schedule/src/main/java/edu/unive/schedule/domain/Schedule.java new file mode 100644 index 0000000..13ff3c9 --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/domain/Schedule.java @@ -0,0 +1,13 @@ +package edu.unive.schedule.domain; + +import lombok.Data; + + +@Data +public class Schedule { + private Long id; + private int pairNumber; + private Long classroomId; + private Long courseId; // ID курса из внешнего микросервиса + private Long teacherId; // ID преподавателя из внешнего микросервиса +} diff --git a/schedule/src/main/java/edu/unive/schedule/domain/entity/ClassroomEntity.java b/schedule/src/main/java/edu/unive/schedule/domain/entity/ClassroomEntity.java new file mode 100644 index 0000000..1e6f2f0 --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/domain/entity/ClassroomEntity.java @@ -0,0 +1,18 @@ +package edu.unive.schedule.domain.entity; + +import jakarta.persistence.*; +import lombok.Data; + +@Data +@Entity +@Table(name = "classroom") +public class ClassroomEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false, unique = true) + private Long id; + @Column(name = "name", nullable = false) + private String name; + @Column(name = "type", nullable = false) + private ClassroomType type; +} diff --git a/schedule/src/main/java/edu/unive/schedule/domain/entity/ClassroomType.java b/schedule/src/main/java/edu/unive/schedule/domain/entity/ClassroomType.java new file mode 100644 index 0000000..4042d6f --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/domain/entity/ClassroomType.java @@ -0,0 +1,6 @@ +package edu.unive.schedule.domain.entity; + +public enum ClassroomType { + LECTURE, + LAB +} diff --git a/schedule/src/main/java/edu/unive/schedule/domain/entity/ScheduleEntity.java b/schedule/src/main/java/edu/unive/schedule/domain/entity/ScheduleEntity.java new file mode 100644 index 0000000..cb93bff --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/domain/entity/ScheduleEntity.java @@ -0,0 +1,25 @@ +package edu.unive.schedule.domain.entity; + +import jakarta.persistence.*; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@Entity +@Table(name = "schedule") +public class ScheduleEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false, unique = true) + private Long id; + @Column(name = "pair_number", nullable = false) + private int pairNumber; + + @ManyToOne + @JoinColumn(name = "classroom_id") + private ClassroomEntity classroom; + + private Long courseId; // ID курса из внешнего микросервиса + private Long teacherId; // ID преподавателя из внешнего микросервиса +} diff --git a/schedule/src/main/java/edu/unive/schedule/domain/mapper/ClassroomEntityMapper.java b/schedule/src/main/java/edu/unive/schedule/domain/mapper/ClassroomEntityMapper.java new file mode 100644 index 0000000..28ee429 --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/domain/mapper/ClassroomEntityMapper.java @@ -0,0 +1,10 @@ +package edu.unive.schedule.domain.mapper; + +import edu.unive.schedule.domain.Classroom; +import edu.unive.schedule.domain.entity.ClassroomEntity; +import org.mapstruct.Mapper; + +@Mapper(componentModel = "spring") +public interface ClassroomEntityMapper { + ClassroomEntity ToEntity(Classroom classroom); +} diff --git a/schedule/src/main/java/edu/unive/schedule/domain/mapper/ClassroomMapper.java b/schedule/src/main/java/edu/unive/schedule/domain/mapper/ClassroomMapper.java new file mode 100644 index 0000000..2fd90dd --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/domain/mapper/ClassroomMapper.java @@ -0,0 +1,10 @@ +package edu.unive.schedule.domain.mapper; + +import edu.unive.schedule.domain.Classroom; +import edu.unive.schedule.domain.entity.ClassroomEntity; +import org.mapstruct.Mapper; + +@Mapper(componentModel = "spring") +public interface ClassroomMapper { + Classroom toDTO(ClassroomEntity classroomEntity); +} diff --git a/schedule/src/main/java/edu/unive/schedule/domain/mapper/ScheduleEntityMapper.java b/schedule/src/main/java/edu/unive/schedule/domain/mapper/ScheduleEntityMapper.java new file mode 100644 index 0000000..8099416 --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/domain/mapper/ScheduleEntityMapper.java @@ -0,0 +1,12 @@ +package edu.unive.schedule.domain.mapper; + +import edu.unive.schedule.domain.Schedule; +import edu.unive.schedule.domain.entity.ScheduleEntity; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(componentModel = "spring") +public interface ScheduleEntityMapper { + @Mapping(source = "classroomId", target = "classroom.id") + ScheduleEntity toEntity(Schedule schedule); +} diff --git a/schedule/src/main/java/edu/unive/schedule/domain/mapper/ScheduleMapper.java b/schedule/src/main/java/edu/unive/schedule/domain/mapper/ScheduleMapper.java new file mode 100644 index 0000000..b1aa00d --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/domain/mapper/ScheduleMapper.java @@ -0,0 +1,12 @@ +package edu.unive.schedule.domain.mapper; + +import edu.unive.schedule.domain.Schedule; +import edu.unive.schedule.domain.entity.ScheduleEntity; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(componentModel = "spring") +public interface ScheduleMapper { + @Mapping(source = "classroomEntity.id", target = "classroomId") + Schedule toDTO(ScheduleEntity classroomEntity); +} diff --git a/schedule/src/main/java/edu/unive/schedule/repository/ClassroomRepository.java b/schedule/src/main/java/edu/unive/schedule/repository/ClassroomRepository.java new file mode 100644 index 0000000..8d5665e --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/repository/ClassroomRepository.java @@ -0,0 +1,10 @@ +package edu.unive.schedule.repository; + +import edu.unive.schedule.domain.entity.ClassroomEntity; +import edu.unive.schedule.domain.entity.ScheduleEntity; +import org.springframework.data.jpa.repository.JpaRepository; + + +public interface ClassroomRepository extends JpaRepository { +} + diff --git a/schedule/src/main/java/edu/unive/schedule/repository/ScheduleRepository.java b/schedule/src/main/java/edu/unive/schedule/repository/ScheduleRepository.java new file mode 100644 index 0000000..a358429 --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/repository/ScheduleRepository.java @@ -0,0 +1,9 @@ +package edu.unive.schedule.repository; + +import edu.unive.schedule.domain.entity.ScheduleEntity; +import org.springframework.data.jpa.repository.JpaRepository; + + +public interface ScheduleRepository extends JpaRepository { +} + diff --git a/schedule/src/main/java/edu/unive/schedule/service/ClassroomService.java b/schedule/src/main/java/edu/unive/schedule/service/ClassroomService.java new file mode 100644 index 0000000..ab084b3 --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/service/ClassroomService.java @@ -0,0 +1,8 @@ +package edu.unive.schedule.service; + +import edu.unive.schedule.domain.Classroom; + +public interface ClassroomService { + void createClassroom(Classroom classroom); + Classroom getClassroomById(Long id); +} diff --git a/schedule/src/main/java/edu/unive/schedule/service/ClassroomServiceImpl.java b/schedule/src/main/java/edu/unive/schedule/service/ClassroomServiceImpl.java new file mode 100644 index 0000000..0debffb --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/service/ClassroomServiceImpl.java @@ -0,0 +1,31 @@ +package edu.unive.schedule.service; + +import edu.unive.schedule.domain.Classroom; +import edu.unive.schedule.domain.mapper.ClassroomEntityMapper; +import edu.unive.schedule.domain.mapper.ClassroomMapper; +import edu.unive.schedule.repository.ClassroomRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ClassroomServiceImpl implements ClassroomService { + + private final ClassroomRepository classroomRepository; + private final ClassroomEntityMapper classroomEntityMapper; + private final ClassroomMapper classroomMapper; + + @Override + @Transactional + public void createClassroom(Classroom classroomDTO) { + var entity = classroomEntityMapper.ToEntity(classroomDTO); + entity.setId(null); + classroomRepository.save(entity); + } + + @Override + public Classroom getClassroomById(Long id) { + return classroomMapper.toDTO(classroomRepository.findById(id).orElse(null)); + } +} \ No newline at end of file diff --git a/schedule/src/main/java/edu/unive/schedule/service/ScheduleService.java b/schedule/src/main/java/edu/unive/schedule/service/ScheduleService.java new file mode 100644 index 0000000..fcf4f4f --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/service/ScheduleService.java @@ -0,0 +1,9 @@ +package edu.unive.schedule.service; + +import edu.unive.schedule.domain.Schedule; + +public interface ScheduleService { + void createSchedule(Schedule schedule); + void updateSchedule(Long id, Schedule schedule); + void deleteSchedule(Long id); +} diff --git a/schedule/src/main/java/edu/unive/schedule/service/ScheduleServiceImpl.java b/schedule/src/main/java/edu/unive/schedule/service/ScheduleServiceImpl.java new file mode 100644 index 0000000..0723a88 --- /dev/null +++ b/schedule/src/main/java/edu/unive/schedule/service/ScheduleServiceImpl.java @@ -0,0 +1,38 @@ +package edu.unive.schedule.service; + +import edu.unive.schedule.domain.Schedule; +import edu.unive.schedule.domain.entity.ScheduleEntity; +import edu.unive.schedule.domain.mapper.ScheduleEntityMapper; +import edu.unive.schedule.repository.ScheduleRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ScheduleServiceImpl implements ScheduleService { + + private final ScheduleRepository scheduleRepository; + + private final ScheduleEntityMapper scheduleEntityMapper; + + @Transactional + @Override + public void createSchedule(Schedule scheduleDTO) { + ScheduleEntity entity = scheduleEntityMapper.toEntity(scheduleDTO); + entity.setId(null); + scheduleRepository.save(entity); + } + + @Transactional + @Override + public void updateSchedule(Long id, Schedule scheduleDTO) { + ScheduleEntity entity = scheduleEntityMapper.toEntity(scheduleDTO); + scheduleRepository.save(entity); + } + + @Override + public void deleteSchedule(Long id) { + scheduleRepository.deleteById(id); + } +} diff --git a/schedule/src/main/resources/application.properties b/schedule/src/main/resources/application.properties deleted file mode 100644 index 27e3fba..0000000 --- a/schedule/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=schedule diff --git a/schedule/src/main/resources/application.yml b/schedule/src/main/resources/application.yml new file mode 100644 index 0000000..5c6d1be --- /dev/null +++ b/schedule/src/main/resources/application.yml @@ -0,0 +1,18 @@ +server: + port: 8280 +spring: + application.name: schedule + datasource: + url: jdbc:postgresql://localhost:5432/u_schedule + username: postgres + password: postgres + flyway: + enabled: true + locations: classpath:db/migration + baseline-on-migrate: true + jpa: + show-sql: true + properties: + hibernate: + format_sql: true + use_sql_comments: true \ No newline at end of file diff --git a/schedule/src/main/resources/db/migration/V1__Init.sql b/schedule/src/main/resources/db/migration/V1__Init.sql new file mode 100644 index 0000000..4d37083 --- /dev/null +++ b/schedule/src/main/resources/db/migration/V1__Init.sql @@ -0,0 +1,16 @@ +CREATE TABLE classroom ( + id BIGSERIAL + CONSTRAINT classroom_pk PRIMARY KEY, + name VARCHAR(255) NOT NULL, + type VARCHAR(50) NOT NULL +); + +CREATE TABLE schedule ( + id BIGSERIAL + CONSTRAINT schedule_pk PRIMARY KEY, + pair_number INT, + classroom_id BIGINT, + course_id BIGINT, + teacher_id BIGINT, + FOREIGN KEY (classroom_id) REFERENCES classroom(id) +); \ No newline at end of file diff --git a/schedule/src/test/java/edu/unive/schedule/ScheduleApplicationTests.java b/schedule/src/test/java/edu/unive/schedule/ScheduleEntityApplicationTests.java similarity index 82% rename from schedule/src/test/java/edu/unive/schedule/ScheduleApplicationTests.java rename to schedule/src/test/java/edu/unive/schedule/ScheduleEntityApplicationTests.java index 776a6df..6be2a53 100644 --- a/schedule/src/test/java/edu/unive/schedule/ScheduleApplicationTests.java +++ b/schedule/src/test/java/edu/unive/schedule/ScheduleEntityApplicationTests.java @@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest -class ScheduleApplicationTests { +class ScheduleEntityApplicationTests { @Test void contextLoads() {