Skip to content
Open

Hw12 #15

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dev/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ services:
- DB_URL=jdbc:postgresql://postgres:5432/postgres?currentSchema=public&stringtype=unspecified
- DB_USERNAME=postgres
- DB_PASSWORD=123
- RANCHER_REST_URL=http://rancher-service:8082
- HANDYMAN_REST_URL=http://handyman-service:8080
depends_on:
- rancher-service
- handyman-service
Expand Down
16 changes: 16 additions & 0 deletions docs/homeworks-logs/hw12.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- [X] Сервис после получения запроса на создание работы, должен сохранить его в таблице.
- [X] Сервис должен найти копателей для всех заказов, которые имеют статус created. Копатели должны иметь подходящие навыки для выполнения заказа (навыки, указанные в запросе от копателей, должны совпадать с теми, что указал огородник).
- [X] Если копатели с похожими навыками найдены, то необходимо отсортировать самых ближайших к огороду и выделить первых трех копателей и создать запрос к системе HandymanService, указав необходимых копателей.
- [X] Иначе - уведомляем сервис RancherService: "По данному запросу копателей не нашлось. Измените объем работ".
- [X] Новый запрос на изменение объема работ должен обновить данные ранее созданого запроса

- [X] В сервисе при получении запроса на работу, копатель может либо принять, либо отклонить заказ. (Для тестирования можете захардкодить ответ. Например, если приходит запрос с копанием огорода, ъ копатель отклоняет его, а если с поливанием - принимает)
- [X] Если заказ принят, в сервисе LandscapeService должны обновить статус заказа.
- [X] Если заказ отклонен - ничего не делаем.
- [X] После того, как копатель принял заказа, необходимо через рандомное время отправить запрос в LandscapeService о том, что работа проделана. Статус заказа должен измениться.
- [X] LandscapeService информирует RancherService об изменении статуса заказа.
- [X] Через рандомное время огородник отправляет запрос в LandscapeService о подтверждении заказа и выставляет оценку работы.

- [ ] При отправке запроса из сервиса RancherService в LandscapeService возникнет ситуация, когда LandscapeService не обработал запрос. (сетевые проблемы, приложение упало и тд). Необходимо повторно выслать запроса из сервиса RancherService и записать данные в таблицу сервиса LandscapeService.
- [ ] Создав запрос из сервиса LandscapeService в HandymanService, у копателя может возникнуть проблема с соединением. Тогда попробовать заново отправить запрос, если запрос не был обработан то, следует создать новый запрос другому копателю.
- [ ] При отправке запроса из сервиса HandymanService в LandscapeService необходимо убедиться в том, что данные записались корретно. Если LandscapeService в момент получения запроса упадет, то необходимо инициировать новый запрос.
4 changes: 4 additions & 0 deletions handyman-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ ext {
}

dependencies {
implementation 'org.n52.jackson:jackson-datatype-jts:1.2.10'
implementation 'org.locationtech.jts:jts-io:1.18.2'
implementation 'org.locationtech.jts:jts-core:1.18.2'

implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'

implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.archie.handymanservice.handyman;

import dev.archie.handymanservice.handyman.dto.CreatingHandymanDto;
import dev.archie.handymanservice.landscape.Order;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -11,6 +12,8 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@RestController
@RequiredArgsConstructor
@RequestMapping("/handymen")
Expand Down Expand Up @@ -53,4 +56,9 @@ public Handyman update(@PathVariable String id, @RequestBody CreatingHandymanDto
public void delete(@PathVariable String id) {
handymanService.delete(id);
}

@PostMapping("/order/{innerId}")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не соотносится с методологией REST

public boolean orderAJob(@PathVariable UUID innerId, @RequestBody Order order) {
return handymanService.orderAJob(innerId, order);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,9 @@

import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.Optional;
import java.util.UUID;

public interface HandymanRepository extends MongoRepository<Handyman, String> {
boolean existsByInnerId(UUID innerId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше добавить чуть больше контекста в наименования

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,23 @@
import dev.archie.handymanservice.handyman.skill.SkillRepository;
import dev.archie.handymanservice.landscape.HandymanClient;
import dev.archie.handymanservice.landscape.LandscapeService;
import dev.archie.handymanservice.landscape.Order;
import dev.archie.handymanservice.landscape.OrderClient;
import dev.archie.handymanservice.landscape.WorkStatus;
import dev.archie.handymanservice.landscape.dto.CreatingOrderDto;
import dev.archie.handymanservice.landscape.dto.HandymanDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

@Service
@RequiredArgsConstructor
@Slf4j
public class HandymanService {

private final HandymanRepository handymanRepository;
Expand All @@ -27,6 +36,7 @@ public class HandymanService {
private final AccountService accountService;

private final HandymanClient handymanClient;
private final OrderClient orderClient;

/**
* @param creatingHandymanDto handyman dto create. Email should not exist
Expand Down Expand Up @@ -62,7 +72,7 @@ public Handyman getById(String id) {
}

/**
* @param id of existing profile
* @param id of existing profile
* @param creatingHandymanDto of new fields. New email should not exist
* @return Profile od updated handyman
*/
Expand Down Expand Up @@ -114,4 +124,39 @@ private Handyman mapUserToHandyman(HandymanDto createdUser, CreatingHandymanDto
.phone(creatingHandymanDto.getPhoneNumber())
.build();
}

public boolean orderAJob(UUID innerId, Order order) {
if (!handymanRepository.existsByInnerId(innerId)) {
throw new NoSuchUserException(innerId.toString());
}
boolean acceptedTheJob = order.getSkills().stream()
.noneMatch(skill -> skill.getName().contains("поливать"));
if (acceptedTheJob) {
CompletableFuture.runAsync(() -> getTheJobDone(order, innerId));
log.info(innerId + " принял работу");
} else {
log.info(innerId + " отказался от работы");
}
return acceptedTheJob;
}

public void getTheJobDone(Order order, UUID innerId) {
Random random = new Random();
try {
Thread.sleep(random.nextLong(4000) + 3000);
} catch (InterruptedException e) {
throw new RuntimeException("Execution was interrupted" + e);
}
order.setStatus(WorkStatus.DONE);
CreatingOrderDto updatingDto = CreatingOrderDto.builder()
.status(order.getStatus())
.fieldId(order.getField().getId())
.userId(innerId)
.workType(order.getWorkType())
.skills(order.getSkills().stream().map(Skill::getName).toList())
.build();
orderClient.update(order.getId(), updatingDto);
log.info(innerId + " выполнил работу");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dev.archie.handymanservice.landscape;


import dev.archie.handymanservice.handyman.skill.Skill;
import dev.archie.handymanservice.landscape.dto.Field;
import lombok.Data;

import java.time.LocalDateTime;
import java.util.Set;

@Data
public class Order {
private Long id;

private WorkType workType;

private WorkStatus status;

private LocalDateTime createdAt;

private Field field;

private Set<Skill> skills;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package dev.archie.handymanservice.landscape;

import dev.archie.handymanservice.landscape.dto.CreatingOrderDto;
import dev.archie.handymanservice.landscape.dto.OrderDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.DeleteMapping;
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;

@FeignClient(name = "order-client", path = "/orders", url = "${application.landscape.rest.url}")
public interface OrderClient {

@PostMapping
OrderDto create(@RequestBody CreatingOrderDto orderDto);

@GetMapping("/{id}")
OrderDto getById(@PathVariable Long id);
@PutMapping("/{id}")
OrderDto update(@PathVariable Long id, @RequestBody CreatingOrderDto orderDto);

@DeleteMapping("/{id}")
void delete(@PathVariable Long id);

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.archie.handymanservice.landscape;

public enum WorkStatus {
CREATED,
IN_PROGRESS,
DONE,
APPROVED
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.archie.handymanservice.landscape;

public enum WorkType {
SHOVEL,
PLANT,
WATER,
SOW
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package dev.archie.handymanservice.landscape.dto;

import dev.archie.handymanservice.landscape.WorkStatus;
import dev.archie.handymanservice.landscape.WorkType;
import lombok.Builder;
import lombok.Data;

import java.util.List;
import java.util.UUID;

@Data
@Builder
public class CreatingOrderDto {

private WorkType workType;

private WorkStatus status;

private Long fieldId;

private UUID userId;

private List<String> skills;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package dev.archie.handymanservice.landscape.dto;

import lombok.Data;

@Data
public class Field {

private Long id;

private String address;

private Double latitude;

private Double longitude;

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package dev.archie.handymanservice.landscape.dto;

import lombok.Data;

@Data
public class FieldDto {

private Long id;

private String address;

private Double latitude;

private Double longitude;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dev.archie.handymanservice.landscape.dto;


import dev.archie.handymanservice.landscape.User;
import dev.archie.handymanservice.landscape.WorkStatus;
import dev.archie.handymanservice.landscape.WorkType;
import lombok.Data;

import java.time.LocalDateTime;
import java.util.List;

@Data
public class OrderDto {
private Long id;

private WorkType workType;

private WorkStatus status;

private LocalDateTime createdAt;

private FieldDto field;

private User user;

private List<SkillDto> skills;
}
4 changes: 4 additions & 0 deletions landscape-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,16 @@ repositories {

ext {
set('testcontainersVersion', "1.17.6")
set('springCloudVersion', "2021.0.6")
}

jar {
enabled = false
}

dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'

implementation 'org.hibernate:hibernate-spatial'
implementation 'org.n52.jackson:jackson-datatype-jts:1.2.10'
implementation 'org.locationtech.jts:jts-io:1.18.2'
Expand Down Expand Up @@ -86,6 +89,7 @@ dependencies {
dependencyManagement {
imports {
mavenBom "org.testcontainers:testcontainers-bom:${testcontainersVersion}"
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class LandscapeApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import org.n52.jackson.datatype.jts.JtsModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

@Configuration
@EnableScheduling
public class LandscapeConfiguration {

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.archie.landscapeservice.field;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import dev.archie.landscapeservice.gardener.Gardener;
Expand Down Expand Up @@ -47,6 +48,7 @@ public class Field {
@JsonDeserialize(contentUsing = GeometryDeserializer.class)
private Geometry area;

@JsonIgnoreProperties("fields")
@ManyToOne
@JoinColumn(name = "gardener_id")
private Gardener gardener;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package dev.archie.landscapeservice.gardener;

import dev.archie.landscapeservice.order.Order;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@FeignClient(name = "gardener-client", url = "${application.rancher.rest.url}", path = "/gardeners")
public interface GardenerClient {

@PostMapping("/notify/missingWorkers")
void notifyAboutMissingWorkers(@RequestBody Order order);

@PostMapping("/notify/orderUpdate")
void notifyAboutOrderUpdate(@RequestBody Order orderDto);
}
Loading