Merge pull request 'tepechin_kirill_lab_3' (#41) from tepechin_kirill_lab_3 into main
Reviewed-on: http://student.git.athene.tech/Alexey/DAS_2023_1/pulls/41
This commit is contained in:
commit
c4c4873091
99
tepechin_kirill_lab_3/README.md
Normal file
99
tepechin_kirill_lab_3/README.md
Normal file
@ -0,0 +1,99 @@
|
||||
## Лабораторная работа №3, ПИбд-42 Тепечин Кирилл
|
||||
|
||||
### Сервисы
|
||||
* `opop-service`
|
||||
* `document-service`
|
||||
|
||||
### Синхронный обмен между микросервисами
|
||||
Синхронное взаимодействие осуществляется через `RestTemplate`
|
||||
|
||||
Пример взаимодействия:
|
||||
|
||||
````java
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
String URL = "http://document-service:8081/document/";
|
||||
restTemplate.getForObject(URL+ opopDto.getDocumentId(), DocumentInfo.class)
|
||||
````
|
||||
|
||||
### Докерфайлы
|
||||
|
||||
````dockerfile
|
||||
FROM eclipse-temurin:17-jdk-alpine
|
||||
VOLUME /tmp
|
||||
ARG JAR_FILE
|
||||
COPY ${JAR_FILE} app.jar
|
||||
ENTRYPOINT ["java","-jar","/app.jar"]
|
||||
````
|
||||
### docker-compose файл
|
||||
````yaml
|
||||
version: '3'
|
||||
services:
|
||||
opop-service:
|
||||
build:
|
||||
context: /opop-service
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
JAR_FILE: build/libs/*.jar
|
||||
ports:
|
||||
- "8080:8080"
|
||||
networks:
|
||||
- my-network
|
||||
environment:
|
||||
server.forward-headers-strategy: framework
|
||||
|
||||
document-service:
|
||||
build:
|
||||
context: /document-service
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
JAR_FILE: build/libs/*.jar
|
||||
ports:
|
||||
- "8081:8081"
|
||||
networks:
|
||||
- my-network
|
||||
environment:
|
||||
server.forward-headers-strategy: framework
|
||||
|
||||
nginx:
|
||||
image: nginx
|
||||
ports:
|
||||
- "80:80"
|
||||
networks:
|
||||
- my-network
|
||||
volumes:
|
||||
- ./nginx-conf:/etc/nginx/conf.d
|
||||
depends_on:
|
||||
- opop-service
|
||||
- document-service
|
||||
|
||||
networks:
|
||||
my-network:
|
||||
driver: bridge
|
||||
````
|
||||
|
||||
### nginx.conf
|
||||
````
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
location /opop-service/ {
|
||||
proxy_pass_request_headers on;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Prefix '/opop-service';
|
||||
proxy_pass http://opop-service:8080/;
|
||||
}
|
||||
|
||||
location /document-service/ {
|
||||
proxy_pass_request_headers on;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Prefix '/document-service';
|
||||
proxy_pass http://document-service:8081/;
|
||||
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
### Ссылка на видео
|
||||
https://vk.com/video170089763_456239482?list=ln-0DBU1KuruzjrZvKRLE
|
||||
|
||||
|
43
tepechin_kirill_lab_3/docker-compose.yml
Normal file
43
tepechin_kirill_lab_3/docker-compose.yml
Normal file
@ -0,0 +1,43 @@
|
||||
version: '3'
|
||||
services:
|
||||
opop-service:
|
||||
build:
|
||||
context: /opop-service
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
JAR_FILE: build/libs/*.jar
|
||||
ports:
|
||||
- "8080:8080"
|
||||
networks:
|
||||
- my-network
|
||||
environment:
|
||||
server.forward-headers-strategy: framework
|
||||
|
||||
document-service:
|
||||
build:
|
||||
context: /document-service
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
JAR_FILE: build/libs/*.jar
|
||||
ports:
|
||||
- "8081:8081"
|
||||
networks:
|
||||
- my-network
|
||||
environment:
|
||||
server.forward-headers-strategy: framework
|
||||
|
||||
nginx:
|
||||
image: nginx
|
||||
ports:
|
||||
- "80:80"
|
||||
networks:
|
||||
- my-network
|
||||
volumes:
|
||||
- ./nginx-conf:/etc/nginx/conf.d
|
||||
depends_on:
|
||||
- opop-service
|
||||
- document-service
|
||||
|
||||
networks:
|
||||
my-network:
|
||||
driver: bridge
|
5
tepechin_kirill_lab_3/document-service/Dockerfile
Normal file
5
tepechin_kirill_lab_3/document-service/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
FROM eclipse-temurin:17-jdk-alpine
|
||||
VOLUME /tmp
|
||||
ARG JAR_FILE
|
||||
COPY ${JAR_FILE} app.jar
|
||||
ENTRYPOINT ["java","-jar","/app.jar"]
|
35
tepechin_kirill_lab_3/document-service/build.gradle
Normal file
35
tepechin_kirill_lab_3/document-service/build.gradle
Normal file
@ -0,0 +1,35 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '3.0.0'
|
||||
id 'io.spring.dependency-management' version '1.1.0'
|
||||
}
|
||||
|
||||
group = 'org.example'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
configurations {
|
||||
compileOnly {
|
||||
extendsFrom annotationProcessor
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
// implementation 'org.mapstruct:mapstruct:1.5.3.Final'
|
||||
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.3'
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
annotationProcessor 'org.projectlombok:lombok'
|
||||
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final'
|
||||
|
||||
|
||||
testImplementation platform('org.junit:junit-bom:5.9.1')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.example;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Document {
|
||||
@JsonView(Views.Private.class)
|
||||
private long id;
|
||||
@JsonView(Views.Public.class)
|
||||
private String text;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package org.example;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DocumentApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DocumentApplication.class, args);
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package org.example;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/document")
|
||||
public class DocumentController {
|
||||
|
||||
@Autowired
|
||||
private DocumentStorage documentStorage;
|
||||
|
||||
@JsonView(Views.Private.class)
|
||||
@GetMapping
|
||||
public List<Document> getAllDocuments(){
|
||||
return documentStorage.getAllDocuments();
|
||||
}
|
||||
@JsonView(Views.Private.class)
|
||||
@GetMapping("/{id}")
|
||||
public Document getDocument(@PathVariable long id){
|
||||
return documentStorage.getDocument(id);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Document addDocument(@RequestBody @JsonView(Views.Public.class) Document document){
|
||||
return documentStorage.addDocument(document);
|
||||
}
|
||||
@PutMapping
|
||||
public void editDocument(@RequestBody Document opopDtoList){
|
||||
documentStorage.editDocument(opopDtoList);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public void deleteDocument(@PathVariable long id){
|
||||
documentStorage.deleteDocument(id);
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||
@ExceptionHandler(Exception.class)
|
||||
public String handleNotFound(Exception e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package org.example;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DocumentStorage {
|
||||
private long currentId = 1;
|
||||
private static final List<Document> documentList = new ArrayList<>();
|
||||
|
||||
public List<Document> getAllDocuments(){
|
||||
return documentList;
|
||||
}
|
||||
|
||||
public Document getDocument(long id){
|
||||
return documentList.get(findIndexById(id));
|
||||
}
|
||||
|
||||
public Document addDocument(Document document){
|
||||
long id = currentId++;
|
||||
document.setId(id);
|
||||
|
||||
documentList.add(document);
|
||||
return document;
|
||||
}
|
||||
|
||||
public void deleteDocument(long id){
|
||||
documentList.remove(documentList.get(findIndexById(id)));
|
||||
}
|
||||
|
||||
public void editDocument(Document document){
|
||||
int index = findIndexById(document.getId());
|
||||
Document docFromDb = documentList.get(index);
|
||||
docFromDb.setText(document.getText());
|
||||
|
||||
documentList.set(index, docFromDb);
|
||||
}
|
||||
|
||||
private int findIndexById(long idToFind) {
|
||||
for (int i = 0; i < documentList.size(); i++) {
|
||||
Document obj = documentList.get(i);
|
||||
if (obj.getId() == idToFind) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package org.example;
|
||||
|
||||
public class Views {
|
||||
public interface Public {}
|
||||
public interface Private extends Public {}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
server:
|
||||
port: 8081
|
||||
forward-headers-strategy=framework:
|
18
tepechin_kirill_lab_3/nginx-conf/nginx.conf
Normal file
18
tepechin_kirill_lab_3/nginx-conf/nginx.conf
Normal file
@ -0,0 +1,18 @@
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
location /opop-service/ {
|
||||
proxy_pass_request_headers on;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Prefix '/opop-service';
|
||||
proxy_pass http://opop-service:8080/;
|
||||
}
|
||||
|
||||
location /document-service/ {
|
||||
proxy_pass_request_headers on;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Prefix '/document-service';
|
||||
proxy_pass http://document-service:8081/;
|
||||
|
||||
}
|
||||
}
|
5
tepechin_kirill_lab_3/opop-service/Dockerfile
Normal file
5
tepechin_kirill_lab_3/opop-service/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
FROM eclipse-temurin:17-jdk-alpine
|
||||
VOLUME /tmp
|
||||
ARG JAR_FILE
|
||||
COPY ${JAR_FILE} app.jar
|
||||
ENTRYPOINT ["java","-jar","/app.jar"]
|
35
tepechin_kirill_lab_3/opop-service/build.gradle
Normal file
35
tepechin_kirill_lab_3/opop-service/build.gradle
Normal file
@ -0,0 +1,35 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '3.0.0'
|
||||
id 'io.spring.dependency-management' version '1.1.0'
|
||||
}
|
||||
|
||||
group = 'org.example'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
configurations {
|
||||
compileOnly {
|
||||
extendsFrom annotationProcessor
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.mapstruct:mapstruct:1.5.3.Final'
|
||||
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.3'
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
annotationProcessor 'org.projectlombok:lombok'
|
||||
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final'
|
||||
|
||||
|
||||
testImplementation platform('org.junit:junit-bom:5.9.1')
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.example;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.example.dto.DocumentInfo;
|
||||
|
||||
import java.util.List;
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Opop {
|
||||
private long id;
|
||||
private String code;
|
||||
private int studyDuration;
|
||||
private DocumentInfo documentInfo;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package org.example;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class OpopApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(OpopApplication.class, args);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package org.example;
|
||||
|
||||
import org.example.dto.OpopDtoCreate;
|
||||
import org.example.dto.OpopDtoDetails;
|
||||
import org.example.dto.OpopDtoList;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/opop")
|
||||
public class OpopController {
|
||||
|
||||
@Autowired
|
||||
private OpopStorage opopStorage;
|
||||
|
||||
@GetMapping
|
||||
public List<OpopDtoList> getAllOpops(){
|
||||
return opopStorage.getAllOpops();
|
||||
}
|
||||
@GetMapping("/{id}")
|
||||
public OpopDtoDetails getOpopDetails(@PathVariable long id){
|
||||
return opopStorage.getOpopDetails(id);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public OpopDtoDetails addOpop(@RequestBody OpopDtoCreate opopDtoCreate){
|
||||
return opopStorage.addOpop(opopDtoCreate);
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
public void editOpop(@RequestBody OpopDtoList opopDtoList){
|
||||
opopStorage.editOpop(opopDtoList);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public void deleteOpop(@PathVariable long id){
|
||||
opopStorage.deleteOpop(id);
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||
@ExceptionHandler(Exception.class)
|
||||
public String handleNotFound(Exception e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package org.example;
|
||||
|
||||
import org.example.dto.OpopDtoCreate;
|
||||
import org.example.dto.OpopDtoDetails;
|
||||
import org.example.dto.OpopDtoList;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
|
||||
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
public interface OpopMapper {
|
||||
@Mapping(target = "documentId", source = "documentInfo.id")
|
||||
OpopDtoList toListDto(Opop opop);
|
||||
OpopDtoDetails toDetailsDto(Opop opop);
|
||||
@Mapping(source = "documentId", target = "documentInfo.id")
|
||||
Opop fromCreateDto(OpopDtoCreate opopDtoCreate);
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package org.example;
|
||||
|
||||
import org.example.dto.DocumentInfo;
|
||||
import org.example.dto.OpopDtoCreate;
|
||||
import org.example.dto.OpopDtoDetails;
|
||||
import org.example.dto.OpopDtoList;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class OpopStorage {
|
||||
@Autowired
|
||||
private OpopMapper opopMapper;
|
||||
private long currentId = 1;
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
private static final List<Opop> opopList = new ArrayList<>();
|
||||
private final String URL = "http://document-service:8081/document/";
|
||||
|
||||
public List<OpopDtoList> getAllOpops(){
|
||||
return opopList.stream().map(opop -> opopMapper.toListDto(opop)).toList();
|
||||
}
|
||||
|
||||
public OpopDtoDetails getOpopDetails(long id){
|
||||
return opopMapper.toDetailsDto(opopList.stream()
|
||||
.filter(opop -> opop.getId() == id).toList().get(0));
|
||||
}
|
||||
|
||||
public OpopDtoDetails addOpop(OpopDtoCreate opopDtoCreate){
|
||||
long id = currentId++;
|
||||
Opop opop = opopMapper.fromCreateDto(opopDtoCreate);
|
||||
opop.setId(id);
|
||||
opop.setDocumentInfo(restTemplate.getForObject(URL+ opopDtoCreate.getDocumentId(), DocumentInfo.class));
|
||||
|
||||
opopList.add(opop);
|
||||
return opopMapper.toDetailsDto(opop);
|
||||
}
|
||||
|
||||
public void deleteOpop(long id){
|
||||
opopList.remove(opopList.stream().filter(opop -> opop.getId() == id).toList().get(0));
|
||||
}
|
||||
|
||||
public void editOpop(OpopDtoList opopDto){
|
||||
int index = findIndexById(opopDto.getId());
|
||||
Opop opop = opopList.get(index);
|
||||
opop.setCode(opopDto.getCode());
|
||||
opop.setStudyDuration(opopDto.getStudyDuration());
|
||||
opop.setDocumentInfo(restTemplate.getForObject(URL+ opopDto.getDocumentId(), DocumentInfo.class));
|
||||
|
||||
opopList.set(index, opop);
|
||||
}
|
||||
|
||||
private int findIndexById(long idToFind) {
|
||||
for (int i = 0; i < opopList.size(); i++) {
|
||||
Opop obj = opopList.get(i);
|
||||
if (obj.getId() == idToFind) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package org.example.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DocumentInfo {
|
||||
private long id;
|
||||
private String text;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package org.example.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OpopDtoCreate {
|
||||
private String code;
|
||||
private int studyDuration;
|
||||
private int documentId;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package org.example.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OpopDtoDetails {
|
||||
private long id;
|
||||
private String code;
|
||||
private int studyDuration;
|
||||
private DocumentInfo documentInfo;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package org.example.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OpopDtoList {
|
||||
private long id;
|
||||
private String code;
|
||||
private int studyDuration;
|
||||
private int documentId;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
server:
|
||||
forward-headers-strategy=framework:
|
Loading…
Reference in New Issue
Block a user