diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml index b87cf19..b64a903 100644 --- a/dev/docker-compose.yml +++ b/dev/docker-compose.yml @@ -16,7 +16,7 @@ services: environment: - SERVICE_ADDRESS=0.0.0.0 - MONGO_DB_URI=mongodb://mongo:27017/handyman - - LANDSCAPE_REST_URL=http://landscape-service:8081/ + - LANDSCAPE_REST_URL=http://landscape-service:8081 - PG_DB_URL=jdbc:postgresql://postgres:5432/postgres?currentSchema=public&stringtype=unspecified - PG_DB_USERNAME=postgres - PG_DB_PASSWORD=123 @@ -52,7 +52,7 @@ services: environment: - SERVICE_ADDRESS=0.0.0.0 - MONGO_DB_URI=mongodb://mongo:27017/rancher - - LANDSCAPE_REST_URL=http://landscape-service:8081/ + - LANDSCAPE_REST_URL=http://landscape-service:8081 - PG_DB_URL=jdbc:postgresql://postgres:5432/postgres?currentSchema=public&stringtype=unspecified - PG_DB_USERNAME=postgres - PG_DB_PASSWORD=123 diff --git a/docs/homeworks-logs/hw11.md b/docs/homeworks-logs/hw11.md new file mode 100644 index 0000000..b0d2b75 --- /dev/null +++ b/docs/homeworks-logs/hw11.md @@ -0,0 +1,4 @@ +## Сделал: + - [X] перенос сервисов handyman и rancher на Mongo + - [X] ручка для отчетов + - [ ] 100к документов в Монгу \ No newline at end of file diff --git a/handyman-service/build.gradle b/handyman-service/build.gradle index f23b06a..c0ac897 100644 --- a/handyman-service/build.gradle +++ b/handyman-service/build.gradle @@ -15,7 +15,6 @@ plugins { id 'io.spring.dependency-management' version '1.0.15.RELEASE' id 'java-library' id 'com.google.protobuf' version "${protobufPluginVersion}" - id 'org.liquibase.gradle' version '2.2.0' } group = 'dev.archie' @@ -67,17 +66,9 @@ ext { dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - runtimeOnly 'org.postgresql:postgresql' implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' testImplementation "org.testcontainers:mongodb:1.18.0" - liquibaseRuntime 'org.mongodb:bson:4.9.0' - liquibaseRuntime 'org.mongodb:mongodb-driver-core:4.9.0' - liquibaseRuntime 'org.mongodb:mongodb-driver-sync:4.9.0' - liquibaseRuntime 'org.liquibase.ext:liquibase-mongodb:4.20.0' implementation 'org.liquibase:liquibase-core:4.20.0' - liquibaseRuntime 'info.picocli:picocli:4.6.1' - implementation 'org.yaml:snakeyaml:2.0' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'io.micrometer:micrometer-registry-prometheus' diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/account/Account.java b/handyman-service/src/main/java/dev/archie/handymanservice/account/Account.java index 9d7c321..f529a0d 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/account/Account.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/account/Account.java @@ -2,74 +2,37 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import dev.archie.handymanservice.account.bank.Bank; -import dev.archie.handymanservice.user.HandymanUser; +import dev.archie.handymanservice.handyman.Handyman; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import org.hibernate.Hibernate; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import java.util.Objects; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.DocumentReference; @Builder(toBuilder = true) -@AllArgsConstructor -@NoArgsConstructor @Getter @Setter -@Entity -@Table(name = "account") +@AllArgsConstructor +@NoArgsConstructor +@Document(collection = "accounts") public class Account { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id", nullable = false) - private Long id; + private String id; + + private Long innerId; @JsonIgnoreProperties("accounts") - @ManyToOne - @JoinColumn(name = "handyman_user_id") - private HandymanUser handymanUser; + @DocumentReference + private Handyman handyman; - @Column(name = "card_number") private String cardNumber; - @Enumerated(EnumType.STRING) - @Column(name = "payment_system") private PaymentSystem paymentSystem; - @ManyToOne - @JoinColumn(name = "bank_id") + @DocumentReference private Bank bank; - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; - Account account = (Account) o; - return getId() != null && Objects.equals(getId(), account.getId()); - } - - @Override - public int hashCode() { - return getClass().hashCode(); - } - - @Override - public String toString() { - return getClass().getSimpleName() + "(" + - "id = " + id + ", " + - "handymanUser = " + handymanUser + ", " + - "cardNumber = " + cardNumber + ", " + - "paymentSystem = " + paymentSystem + ")"; - } } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountController.java b/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountController.java index 88f2d25..626388d 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountController.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountController.java @@ -24,22 +24,22 @@ public class AccountController { private final BankService bankService; @PostMapping("/{handymanUserId}") - public Account create(@RequestBody CreatingAccountDto accountDto, @PathVariable Long handymanUserId) { + public Account create(@RequestBody CreatingAccountDto accountDto, @PathVariable String handymanUserId) { return accountService.create(accountDto, handymanUserId); } @GetMapping("/{id}") - public Account getById(Long id) { + public Account getById(@PathVariable String id) { return accountService.getById(id); } @PutMapping("/{id}") - public Account update(@RequestBody CreatingAccountDto accountDto, @PathVariable Long id) { + public Account update(@RequestBody CreatingAccountDto accountDto, @PathVariable String id) { return accountService.update(accountDto, id); } @DeleteMapping("/{id}") - public void delete(@PathVariable Long id) { + public void delete(@PathVariable String id) { accountService.delete(id); } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountRepository.java b/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountRepository.java index 8fa729c..d158a5c 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountRepository.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountRepository.java @@ -1,6 +1,6 @@ package dev.archie.handymanservice.account; -import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.mongodb.repository.MongoRepository; -public interface AccountRepository extends JpaRepository { +public interface AccountRepository extends MongoRepository { } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountService.java b/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountService.java index 985238c..ad3fe69 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountService.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/account/AccountService.java @@ -3,9 +3,11 @@ import dev.archie.handymanservice.account.bank.BankService; import dev.archie.handymanservice.account.dto.CreatingAccountDto; import dev.archie.handymanservice.account.exception.NoSuchAccountException; +import dev.archie.handymanservice.handyman.Handyman; +import dev.archie.handymanservice.handyman.HandymanRepository; import dev.archie.handymanservice.handyman.exception.NoSuchHandymanUserException; -import dev.archie.handymanservice.user.HandymanUser; -import dev.archie.handymanservice.user.HandymanUserRepository; +import dev.archie.handymanservice.landscape.AccountClient; +import dev.archie.handymanservice.landscape.dto.AccountDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -14,41 +16,55 @@ public class AccountService { private final AccountRepository accountRepository; - private final HandymanUserRepository handymanUserRepository; + private final AccountClient accountClient; + private final HandymanRepository handymanRepository; private final BankService bankService; - public Account create(CreatingAccountDto accountDto, Long handymanUserId) { - HandymanUser user = getHandymanUserById(handymanUserId); + public Account create(CreatingAccountDto accountDto, String handymanUserId) { + Handyman user = getHandymanUserById(handymanUserId); + AccountDto registeredAccount = accountClient.create(accountDto, user.getInnerId()); Account account = mapCreatingAccountDtoToAccount(accountDto, user); + account.setInnerId(registeredAccount.getId()); + account.setHandyman(user); account.setBank(bankService.getBankByName(accountDto.getBankName())); - return accountRepository.save(account); + + account = accountRepository.save(account); + user.getAccounts().add(account); + handymanRepository.save(user); + return account; } - public Account getById(Long id) { + public Account getById(String id) { return accountRepository.findById(id) .orElseThrow(() -> new NoSuchAccountException(id)); } - public Account update(CreatingAccountDto accountDto, Long id) { + public Account update(CreatingAccountDto accountDto, String id) { Account account = getById(id); - Account updatedAccount = mapCreatingAccountDtoToAccount(accountDto, account.getHandymanUser()); - account.setBank(bankService.getBankByName(accountDto.getBankName())); - updatedAccount.setId(id); + accountClient.update(accountDto, account.getInnerId()); + Account updatedAccount = mapCreatingAccountDtoToAccount(accountDto, account.getHandyman()); + updatedAccount.setId(account.getId()); + updatedAccount.setInnerId(account.getInnerId()); + updatedAccount.setBank(bankService.getBankByName(accountDto.getBankName())); + updatedAccount.setHandyman(account.getHandyman()); return accountRepository.save(updatedAccount); } - public void delete(Long id) { - accountRepository.delete(getById(id)); + public void delete(String id) { + Account account = getById(id); + accountClient.delete(account.getInnerId()); + accountRepository.delete(account); } - private HandymanUser getHandymanUserById(Long handymanUserId) { - return handymanUserRepository.findById(handymanUserId) + private Handyman getHandymanUserById(String handymanUserId) { + return handymanRepository.findById(handymanUserId) .orElseThrow(() -> new NoSuchHandymanUserException(handymanUserId)); } - private Account mapCreatingAccountDtoToAccount(CreatingAccountDto accountDto, HandymanUser user) { + private Account mapCreatingAccountDtoToAccount(CreatingAccountDto accountDto, + Handyman user) { return Account.builder() - .handymanUser(user) + .handyman(user) .cardNumber(accountDto.getCardNumber()) .paymentSystem(accountDto.getPaymentSystem()) .build(); diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/Bank.java b/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/Bank.java index b06b675..59c81a6 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/Bank.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/Bank.java @@ -1,26 +1,23 @@ package dev.archie.handymanservice.account.bank; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; @Getter @Setter -@Entity -@Table(name = "banks") +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Document(collection = "banks") public class Bank { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id", nullable = false) - private Long id; + private String id; - @Column(name = "name", nullable = false) private String name; } \ No newline at end of file diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/BankRepository.java b/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/BankRepository.java index 1247ecd..9ad47e9 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/BankRepository.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/BankRepository.java @@ -1,9 +1,9 @@ package dev.archie.handymanservice.account.bank; -import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.mongodb.repository.MongoRepository; import java.util.Optional; -public interface BankRepository extends JpaRepository { +public interface BankRepository extends MongoRepository { Optional findByName(String name); } \ No newline at end of file diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/BankService.java b/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/BankService.java index 09f666d..b0336c6 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/BankService.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/account/bank/BankService.java @@ -1,16 +1,35 @@ package dev.archie.handymanservice.account.bank; -import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.Arrays; import java.util.List; @Service -@RequiredArgsConstructor public class BankService { + private static final Bank[] BANKS = new Bank[]{ + Bank.builder().name("InterGalactic Banking Clan").build(), + Bank.builder().name("Gringotts").build(), + Bank.builder().name("ScaminaBank").build(), + Bank.builder().name("Trinance").build(), + Bank.builder().name("StonksBank").build(), + Bank.builder().name("DogeBank").build(), + Bank.builder().name("PepegaBank").build(), + Bank.builder().name("ToTheMoonBank").build(), + Bank.builder().name("RickRollBank").build(), + Bank.builder().name("YetAnotherBank").build() + }; + private final BankRepository bankRepository; + public BankService(BankRepository bankRepository) { + this.bankRepository = bankRepository; + Arrays.stream(BANKS) + .forEach(bank -> bankRepository.findByName(bank.getName()) + .orElseGet(() -> bankRepository.save(bank))); + } + public List getAll() { return bankRepository.findAll(); } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/account/dto/CreatingAccountDto.java b/handyman-service/src/main/java/dev/archie/handymanservice/account/dto/CreatingAccountDto.java index 35480be..bf04441 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/account/dto/CreatingAccountDto.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/account/dto/CreatingAccountDto.java @@ -3,15 +3,11 @@ import dev.archie.handymanservice.account.PaymentSystem; import lombok.Data; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; - @Data public class CreatingAccountDto { private String cardNumber; - @Enumerated(EnumType.STRING) private PaymentSystem paymentSystem; private String bankName; diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/account/exception/NoSuchAccountException.java b/handyman-service/src/main/java/dev/archie/handymanservice/account/exception/NoSuchAccountException.java index 704ff82..280ae87 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/account/exception/NoSuchAccountException.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/account/exception/NoSuchAccountException.java @@ -5,7 +5,7 @@ public class NoSuchAccountException extends ResponseStatusException { - public NoSuchAccountException(Long id) { + public NoSuchAccountException(String id) { super(HttpStatus.NOT_FOUND, "No such account with id: " + id); } } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/Handyman.java b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/Handyman.java index 2755134..c5617e7 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/Handyman.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/Handyman.java @@ -1,14 +1,24 @@ package dev.archie.handymanservice.handyman; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import dev.archie.handymanservice.account.Account; +import dev.archie.handymanservice.handyman.skill.Skill; +import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.DocumentReference; import java.util.List; import java.util.UUID; -@Data +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor @Builder @Document public class Handyman { @@ -22,6 +32,22 @@ public class Handyman { private Double longitude; - private List skills; + private String firstName; + + private String lastName; + + private String email; + + private String phone; + + private byte[] photo; + + @JsonIgnoreProperties("handyman") + @DocumentReference + private List accounts; + + @JsonIgnoreProperties("handyman") + @DocumentReference + private List skills; } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/HandymanController.java b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/HandymanController.java index 856ba7b..05f22eb 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/HandymanController.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/HandymanController.java @@ -23,7 +23,7 @@ public class HandymanController { * @return Created profile */ @PostMapping - public Profile create(@RequestBody CreatingHandymanDto creatingHandymanDto) { + public Handyman create(@RequestBody CreatingHandymanDto creatingHandymanDto) { return handymanService.create(creatingHandymanDto); } @@ -32,8 +32,8 @@ public Profile create(@RequestBody CreatingHandymanDto creatingHandymanDto) { * @return found profile */ @GetMapping("/{id}") - public Profile getById(@PathVariable String id) { - return handymanService.getProfileById(id); + public Handyman getById(@PathVariable String id) { + return handymanService.getById(id); } /** @@ -42,7 +42,7 @@ public Profile getById(@PathVariable String id) { * @return Profile od updated handyman */ @PutMapping("/{id}") - public Profile update(@PathVariable String id, @RequestBody CreatingHandymanDto creatingHandymanDto) { + public Handyman update(@PathVariable String id, @RequestBody CreatingHandymanDto creatingHandymanDto) { return handymanService.update(id, creatingHandymanDto); } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/HandymanService.java b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/HandymanService.java index 86f1b13..97c1439 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/HandymanService.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/HandymanService.java @@ -1,44 +1,55 @@ package dev.archie.handymanservice.handyman; +import dev.archie.handymanservice.account.Account; +import dev.archie.handymanservice.account.AccountService; import dev.archie.handymanservice.handyman.dto.CreatingHandymanDto; import dev.archie.handymanservice.handyman.exception.NoSuchUserException; -import dev.archie.handymanservice.landscape.CreatingUserDto; +import dev.archie.handymanservice.handyman.skill.Skill; +import dev.archie.handymanservice.handyman.skill.SkillRepository; +import dev.archie.handymanservice.landscape.HandymanClient; import dev.archie.handymanservice.landscape.LandscapeService; -import dev.archie.handymanservice.landscape.User; +import dev.archie.handymanservice.landscape.dto.HandymanDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.List; + @Service @RequiredArgsConstructor public class HandymanService { - private static final long HANDYMAN_USER_TYPE_ID = 2; - private final HandymanRepository handymanRepository; private final LandscapeService landscapeService; + private final SkillRepository skillRepository; + + private final AccountService accountService; + + private final HandymanClient handymanClient; + /** * @param creatingHandymanDto handyman dto create. Email should not exist * @return Created profile */ - public Profile create(CreatingHandymanDto creatingHandymanDto) { - CreatingUserDto creatingUserDto = mapCreatingHandymanDtoToUserOne(creatingHandymanDto); - User createdUser = landscapeService.createUser(creatingUserDto); - Handyman handyman = mapUserToHandyman(createdUser, creatingHandymanDto); - handyman.setInnerId(createdUser.getId()); - handymanRepository.insert(handyman); - return new Profile(handyman, createdUser); - } + public Handyman create(CreatingHandymanDto creatingHandymanDto) { + HandymanDto handymanDto = handymanClient.create(creatingHandymanDto); - /** - * @param id for existing profile - * @return found profile - */ - public Profile getProfileById(String id) { - Handyman handyman = getById(id); - User user = landscapeService.getById(handyman.getInnerId()); - return new Profile(handyman, user); + try { + List skills = saveSkills(creatingHandymanDto); + Handyman handyman = mapUserToHandyman(handymanDto, creatingHandymanDto); + handyman.setInnerId(handymanDto.getId()); + handyman.setSkills(skills); + handyman = handymanRepository.insert(handyman); + + String handymanId = handyman.getId(); + List accounts = saveAccounts(creatingHandymanDto, handymanId); + handyman.setAccounts(accounts); + return handymanRepository.save(handyman); + } catch (Throwable anyException) { + landscapeService.delete(handymanDto.getId()); + throw anyException; + } } /** @@ -55,14 +66,17 @@ public Handyman getById(String id) { * @param creatingHandymanDto of new fields. New email should not exist * @return Profile od updated handyman */ - public Profile update(String id, CreatingHandymanDto creatingHandymanDto) { + public Handyman update(String id, CreatingHandymanDto creatingHandymanDto) { Handyman handyman = getById(id); - CreatingUserDto creatingUserDto = mapCreatingHandymanDtoToUserOne(creatingHandymanDto); - User updatedUser = landscapeService.update(handyman.getInnerId(), creatingUserDto); - Handyman updatedHandyman = mapUserToHandyman(updatedUser, creatingHandymanDto); + HandymanDto updated = handymanClient.update(handyman.getInnerId(), creatingHandymanDto); + Handyman updatedHandyman = mapUserToHandyman(updated, creatingHandymanDto); updatedHandyman.setId(handyman.getId()); handymanRepository.save(updatedHandyman); - return new Profile(updatedHandyman, updatedUser); + List accounts = saveAccounts(creatingHandymanDto, updatedHandyman.getId()); + List skills = saveSkills(creatingHandymanDto); + updatedHandyman.setAccounts(accounts); + updatedHandyman.setSkills(skills); + return handymanRepository.save(updatedHandyman); } /** @@ -70,27 +84,34 @@ public Profile update(String id, CreatingHandymanDto creatingHandymanDto) { */ public void delete(String id) { Handyman handyman = getById(id); - landscapeService.delete(handyman.getInnerId()); + handymanClient.delete(handyman.getInnerId()); handymanRepository.delete(handyman); } - private CreatingUserDto mapCreatingHandymanDtoToUserOne(CreatingHandymanDto creatingHandymanDto) { - return CreatingUserDto.builder() - .email(creatingHandymanDto.getEmail()) - .login(creatingHandymanDto.getLogin()) - .longitude(creatingHandymanDto.getLongitude()) - .latitude(creatingHandymanDto.getLatitude()) - .phoneNumber(creatingHandymanDto.getPhoneNumber()) - .userTypeId(HANDYMAN_USER_TYPE_ID) - .build(); + private List saveSkills(CreatingHandymanDto creatingHandymanDto) { + return creatingHandymanDto.getSkills().stream() + .map(skillName -> Skill.builder() + .name(skillName) + .build()) + .map(skillRepository::save) + .toList(); } - private Handyman mapUserToHandyman(User createdUser, CreatingHandymanDto creatingHandymanDto) { + private List saveAccounts(CreatingHandymanDto creatingHandymanDto, String handymanId) { + return creatingHandymanDto.getAccounts().stream() + .map(accountDto -> accountService.create(accountDto, handymanId)) + .toList(); + } + + private Handyman mapUserToHandyman(HandymanDto createdUser, CreatingHandymanDto creatingHandymanDto) { return Handyman.builder() .longitude(createdUser.getLongitude()) .latitude(createdUser.getLatitude()) .innerId(createdUser.getId()) - .skills(creatingHandymanDto.getSkills()) + .firstName(creatingHandymanDto.getFirstName()) + .lastName(creatingHandymanDto.getLastName()) + .email(creatingHandymanDto.getEmail()) + .phone(creatingHandymanDto.getPhoneNumber()) .build(); } } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/Profile.java b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/Profile.java deleted file mode 100644 index 4f0637b..0000000 --- a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/Profile.java +++ /dev/null @@ -1,15 +0,0 @@ -package dev.archie.handymanservice.handyman; - -import dev.archie.handymanservice.landscape.User; -import lombok.Builder; -import lombok.Data; - -@Data -@Builder -public class Profile { - - Handyman handyman; - - User user; - -} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/dto/CreatingHandymanDto.java b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/dto/CreatingHandymanDto.java index def4d33..6d2adbb 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/dto/CreatingHandymanDto.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/dto/CreatingHandymanDto.java @@ -1,5 +1,6 @@ package dev.archie.handymanservice.handyman.dto; +import dev.archie.handymanservice.account.dto.CreatingAccountDto; import lombok.Builder; import lombok.Data; @@ -21,4 +22,10 @@ public class CreatingHandymanDto { private List skills; + private String firstName; + + private String lastName; + + private List accounts; + } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/exception/NoSuchHandymanUserException.java b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/exception/NoSuchHandymanUserException.java index c7b2f2c..448e48f 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/exception/NoSuchHandymanUserException.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/exception/NoSuchHandymanUserException.java @@ -4,7 +4,7 @@ import org.springframework.web.server.ResponseStatusException; public class NoSuchHandymanUserException extends ResponseStatusException { - public NoSuchHandymanUserException(Long handymanUserId) { + public NoSuchHandymanUserException(String handymanUserId) { super(HttpStatus.NOT_FOUND, "No such handyman user with id: " + handymanUserId); } } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/skill/Skill.java b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/skill/Skill.java new file mode 100644 index 0000000..6181947 --- /dev/null +++ b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/skill/Skill.java @@ -0,0 +1,30 @@ +package dev.archie.handymanservice.handyman.skill; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import dev.archie.handymanservice.handyman.Handyman; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.DocumentReference; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Document(collection = "skills") +public class Skill { + + @Id + private String id; + + private String name; + + @JsonIgnoreProperties("skills") + @DocumentReference + private Handyman handyman; +} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/handyman/skill/SkillRepository.java b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/skill/SkillRepository.java new file mode 100644 index 0000000..164b1df --- /dev/null +++ b/handyman-service/src/main/java/dev/archie/handymanservice/handyman/skill/SkillRepository.java @@ -0,0 +1,6 @@ +package dev.archie.handymanservice.handyman.skill; + +import org.springframework.data.mongodb.repository.MongoRepository; + +public interface SkillRepository extends MongoRepository { +} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/AccountClient.java b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/AccountClient.java new file mode 100644 index 0000000..7ed6a3c --- /dev/null +++ b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/AccountClient.java @@ -0,0 +1,31 @@ +package dev.archie.handymanservice.landscape; + +import dev.archie.handymanservice.account.dto.CreatingAccountDto; +import dev.archie.handymanservice.landscape.dto.AccountDto; +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; + +import java.util.UUID; + +@FeignClient(value = "account-service", url = "${application.landscape.rest.url}", path = "/accounts") +public interface AccountClient { + + @PostMapping("/{handymanId}") + AccountDto create(@RequestBody CreatingAccountDto creatingAccountDto, + @PathVariable UUID handymanId); + + @PutMapping("/{accountId}") + AccountDto update(@RequestBody CreatingAccountDto creatingAccountDto, + @PathVariable Long accountId); + + @GetMapping("/{accountId}") + AccountDto getById(@PathVariable Long accountId); + + @DeleteMapping("/{accountId}") + void delete(@PathVariable Long accountId); +} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/HandymanClient.java b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/HandymanClient.java new file mode 100644 index 0000000..fbf4335 --- /dev/null +++ b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/HandymanClient.java @@ -0,0 +1,30 @@ +package dev.archie.handymanservice.landscape; + +import dev.archie.handymanservice.handyman.dto.CreatingHandymanDto; +import dev.archie.handymanservice.landscape.dto.HandymanDto; +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; + +import java.util.UUID; + +@FeignClient(name = "handyman-client", path = "/handymen", url = "${application.landscape.rest.url}") +public interface HandymanClient { + + @PostMapping + HandymanDto create(@RequestBody CreatingHandymanDto creatingHandymanDto); + + @GetMapping("/{id}") + HandymanDto getById(@PathVariable UUID id); + + @PutMapping("/{id}") + HandymanDto update(@PathVariable UUID id, @RequestBody CreatingHandymanDto creatingHandymanDto); + + @DeleteMapping("/{id}") + void delete(@PathVariable UUID id); + +} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/LandscapeService.java b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/LandscapeService.java index 484a3bc..19ee713 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/LandscapeService.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/LandscapeService.java @@ -1,8 +1,12 @@ package dev.archie.handymanservice.landscape; import dev.archie.handymanservice.handyman.exception.UnableToConnectToInnerService; +import dev.archie.handymanservice.landscape.dto.CreatingUserDto; +import feign.FeignException; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; import java.util.UUID; @@ -10,12 +14,15 @@ @RequiredArgsConstructor public class LandscapeService { - private final LandscapeClient landscapeClient; + private final UserClient userClient; public User createUser(CreatingUserDto creatingUserDto) { try { - return landscapeClient.create(creatingUserDto); - } catch (Exception e) { + return userClient.create(creatingUserDto); + } catch (FeignException.FeignClientException e) { + throw new ResponseStatusException(HttpStatus.valueOf(e.status()), e.getMessage()); + } + catch (Exception e) { throw new UnableToConnectToInnerService(); } } @@ -23,21 +30,31 @@ public User createUser(CreatingUserDto creatingUserDto) { public User update(UUID id, CreatingUserDto creatingUserDto) { try { - return landscapeClient.update(id, creatingUserDto); - } catch (Exception e) { + return userClient.update(id, creatingUserDto); + } catch (FeignException.FeignClientException e) { + throw new ResponseStatusException(HttpStatus.valueOf(e.status()), e.getMessage()); + }catch (Exception e) { throw new UnableToConnectToInnerService(); } } public void delete(UUID id) { try { - landscapeClient.delete(id); + userClient.delete(id); + }catch (FeignException.FeignClientException e) { + throw new ResponseStatusException(HttpStatus.valueOf(e.status()), e.getMessage()); } catch (Exception e) { throw new UnableToConnectToInnerService(); } } public User getById(UUID id) { - return landscapeClient.getById(id); + try { + return userClient.getById(id); + }catch (FeignException.FeignClientException e) { + throw new ResponseStatusException(HttpStatus.valueOf(e.status()), e.getMessage()); + } catch (Exception e) { + throw new UnableToConnectToInnerService(); + } } } diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/LandscapeClient.java b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/UserClient.java similarity index 90% rename from handyman-service/src/main/java/dev/archie/handymanservice/landscape/LandscapeClient.java rename to handyman-service/src/main/java/dev/archie/handymanservice/landscape/UserClient.java index 722aa74..10cfa34 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/LandscapeClient.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/UserClient.java @@ -1,5 +1,6 @@ package dev.archie.handymanservice.landscape; +import dev.archie.handymanservice.landscape.dto.CreatingUserDto; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -11,7 +12,7 @@ import java.util.UUID; @FeignClient(value = "user-service", url = "${application.landscape.rest.url}") -public interface LandscapeClient { +public interface UserClient { @PostMapping("/users") User create(@RequestBody CreatingUserDto creatingUserDto); diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/AccountDto.java b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/AccountDto.java new file mode 100644 index 0000000..c899bf2 --- /dev/null +++ b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/AccountDto.java @@ -0,0 +1,21 @@ +package dev.archie.handymanservice.landscape.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import dev.archie.handymanservice.account.PaymentSystem; +import lombok.Data; + +@Data +public class AccountDto { + + private Long id; + + private String cardNumber; + + private PaymentSystem paymentSystem; + + private BankDto bank; + + @JsonIgnoreProperties("accounts") + private HandymanDto handyman; + +} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/BankDto.java b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/BankDto.java new file mode 100644 index 0000000..776d9e8 --- /dev/null +++ b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/BankDto.java @@ -0,0 +1,9 @@ +package dev.archie.handymanservice.landscape.dto; + +import lombok.Data; + +@Data +public class BankDto { + private Long id; + private String name; +} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/landscape/CreatingUserDto.java b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/CreatingUserDto.java similarity index 84% rename from rancher-service/src/main/java/dev/archie/rancherservice/landscape/CreatingUserDto.java rename to handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/CreatingUserDto.java index bd05e00..91b94ad 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/landscape/CreatingUserDto.java +++ b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/CreatingUserDto.java @@ -1,4 +1,4 @@ -package dev.archie.rancherservice.landscape; +package dev.archie.handymanservice.landscape.dto; import lombok.Builder; import lombok.Data; diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/HandymanDto.java b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/HandymanDto.java new file mode 100644 index 0000000..9d64667 --- /dev/null +++ b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/HandymanDto.java @@ -0,0 +1,42 @@ +package dev.archie.handymanservice.landscape.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import dev.archie.handymanservice.landscape.UserType; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +@Data +public class HandymanDto { + private UUID id; + + private String login; + + private String email; + + private String phoneNumber; + + private LocalDateTime createdAt; + + private LocalDateTime lastUpdatedAt; + + private Double latitude; + + private Double longitude; + + private UserType userType; + + private String firstName; + + private String lastName; + + private byte[] photo; + + @JsonIgnoreProperties("accounts") + private List accounts; + + @JsonIgnoreProperties("handyman") + private List skills; +} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/SkillDto.java b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/SkillDto.java new file mode 100644 index 0000000..cea735b --- /dev/null +++ b/handyman-service/src/main/java/dev/archie/handymanservice/landscape/dto/SkillDto.java @@ -0,0 +1,15 @@ +package dev.archie.handymanservice.landscape.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +@Data +public class SkillDto { + + private Long id; + + private String name; + + @JsonIgnoreProperties("skills") + private HandymanDto handyman; +} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUser.java b/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUser.java deleted file mode 100644 index def1559..0000000 --- a/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUser.java +++ /dev/null @@ -1,62 +0,0 @@ -package dev.archie.handymanservice.user; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import dev.archie.handymanservice.account.Account; -import dev.archie.handymanservice.user.skill.Skill; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.hibernate.annotations.Type; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import java.util.List; - - -@Builder(toBuilder = true) -@AllArgsConstructor -@NoArgsConstructor -@Getter -@Setter -@Entity -@Table(name = "handyman_user") -public class HandymanUser { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id", nullable = false) - private Long id; - - @Column(name = "first_name", nullable = false) - private String firstName; - - @Column(name = "last_name", nullable = false) - private String lastName; - - @Column(name = "email", nullable = false) - private String email; - - @Column(name = "phone") - private String phone; - - @Type(type="org.hibernate.type.BinaryType") - @Column(name = "photo") - private byte[] photo; - - @JsonIgnoreProperties("handymanUser") - @OneToMany(mappedBy = "handymanUser", cascade = CascadeType.REMOVE, orphanRemoval = true) - private List accounts; - - @JsonIgnoreProperties("handymanUser") - @OneToMany(mappedBy = "handymanUser", cascade = CascadeType.REMOVE, orphanRemoval = true) - private List skills; - -} \ No newline at end of file diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUserController.java b/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUserController.java deleted file mode 100644 index 3aa4061..0000000 --- a/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUserController.java +++ /dev/null @@ -1,56 +0,0 @@ -package dev.archie.handymanservice.user; - -import dev.archie.handymanservice.user.dto.CreatingHandymanUserDto; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -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; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; - -@RestController -@RequestMapping("users") -@RequiredArgsConstructor -public class HandymanUserController { - - private final HandymanUserService userService; - - @PostMapping - public HandymanUser create(@RequestBody CreatingHandymanUserDto handymanUserDto) throws IOException { - return userService.create(handymanUserDto); - } - - @PostMapping("/photo/{id}") - public HandymanUser publishPhoto(@RequestParam MultipartFile photo, @PathVariable Long id) throws IOException { - return userService.publishPhoto(id, photo); - } - - @GetMapping("/{id}") - public HandymanUser getById(@PathVariable Long id) { - return userService.getById(id); - } - - @PutMapping("/{id}") - public HandymanUser update(@RequestBody CreatingHandymanUserDto handymanUserDto, @PathVariable Long id) { - return userService.update(handymanUserDto, id); - } - - @DeleteMapping("/{id}") - public void delete(@PathVariable Long id) { - userService.delete(id); - } - - @GetMapping - public Page getAll(@RequestParam(name = "size") int pageSize, - @RequestParam(name = "number") int pageNumber) { - return userService.getAll(pageSize, pageNumber); - } -} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUserRepository.java b/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUserRepository.java deleted file mode 100644 index ffb9d81..0000000 --- a/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUserRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.archie.handymanservice.user; - -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; - -public interface HandymanUserRepository extends JpaRepository { - Optional findByEmail(String email); - - boolean existsByEmail(String email); -} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUserService.java b/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUserService.java deleted file mode 100644 index 9aca479..0000000 --- a/handyman-service/src/main/java/dev/archie/handymanservice/user/HandymanUserService.java +++ /dev/null @@ -1,120 +0,0 @@ -package dev.archie.handymanservice.user; - -import dev.archie.handymanservice.account.Account; -import dev.archie.handymanservice.account.AccountService; -import dev.archie.handymanservice.account.dto.CreatingAccountDto; -import dev.archie.handymanservice.handyman.exception.NoSuchHandymanUserException; -import dev.archie.handymanservice.user.dto.CreatingHandymanUserDto; -import dev.archie.handymanservice.user.exception.HandymanUserAlreadyExistsException; -import dev.archie.handymanservice.user.skill.Skill; -import dev.archie.handymanservice.user.skill.SkillRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -@Service -@RequiredArgsConstructor -public class HandymanUserService { - - private final HandymanUserRepository handymanUserRepository; - private final AccountService accountService; - private final SkillRepository skillRepository; - - @Transactional - public HandymanUser create(CreatingHandymanUserDto handymanUserDto) { - HandymanUser user = mapCreatingHandymanUserDtoToHandymanUser(handymanUserDto); - String email = user.getEmail(); - if (handymanUserRepository.existsByEmail(email)) { - throw new HandymanUserAlreadyExistsException(email); - } - user = handymanUserRepository.save(user); - List skills = createSkills(handymanUserDto, user); - user.setSkills(skills); - List accounts = createAccounts(handymanUserDto, user); - user.setAccounts(accounts); - return handymanUserRepository.save(user); - } - - public HandymanUser publishPhoto(Long id, MultipartFile photo) throws IOException { - HandymanUser user = getById(id); - user.setPhoto(photo.getBytes()); - return handymanUserRepository.save(user); - } - - public HandymanUser getById(Long id) { - return handymanUserRepository.findById(id) - .orElseThrow(() -> new NoSuchHandymanUserException(id)); - } - - public HandymanUser update(CreatingHandymanUserDto handymanUserDto, Long id) { - HandymanUser user = getById(id); - String newEmail = handymanUserDto.getEmail(); - Optional possibleUserById = handymanUserRepository.findByEmail(newEmail); - if (possibleUserById.isPresent() && !possibleUserById.get().equals(user)) { - throw new HandymanUserAlreadyExistsException(newEmail); - } - user.setEmail(newEmail); - user.setPhone(handymanUserDto.getPhone()); - user.setFirstName(handymanUserDto.getFirstName()); - user.setLastName(handymanUserDto.getLastName()); - return handymanUserRepository.save(user); - } - - public void delete(Long id) { - handymanUserRepository.deleteById(id); - } - - private HandymanUser mapCreatingHandymanUserDtoToHandymanUser(CreatingHandymanUserDto handymanUserDto) { - return HandymanUser.builder() - .email(handymanUserDto.getEmail()) - .phone(handymanUserDto.getPhone()) - .firstName(handymanUserDto.getFirstName()) - .lastName(handymanUserDto.getLastName()) - .build(); - } - - private List createSkills(CreatingHandymanUserDto handymanUserDto, HandymanUser user) { - List skills = new ArrayList<>(); - for (String skillName : handymanUserDto.getSkills()) { - Skill skill = createSkill(user, skillName); - skills.add(skill); - } - return skills; - } - - private Skill createSkill(HandymanUser user, String skillName) { - Skill skill = Skill.builder() - .handymanUser(user) - .name(skillName) - .build(); - return skillRepository.save(skill); - } - - private List createAccounts(CreatingHandymanUserDto handymanUserDto, HandymanUser user) { - List accounts = new ArrayList<>(); - List accountsDto = handymanUserDto.getAccounts(); - if (accountsDto == null) { - accountsDto = Collections.emptyList(); - } - for (CreatingAccountDto accountDto : accountsDto) { - Account account = accountService.create(accountDto, user.getId()); - accounts.add(account); - } - return accounts; - } - - public Page getAll(int pageSize, int pageNumber) { - PageRequest request = PageRequest.of(pageNumber, pageSize, Sort.by("email")); - return handymanUserRepository.findAll(request); - } -} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/user/dto/CreatingHandymanUserDto.java b/handyman-service/src/main/java/dev/archie/handymanservice/user/dto/CreatingHandymanUserDto.java deleted file mode 100644 index ba6e7c9..0000000 --- a/handyman-service/src/main/java/dev/archie/handymanservice/user/dto/CreatingHandymanUserDto.java +++ /dev/null @@ -1,37 +0,0 @@ -package dev.archie.handymanservice.user.dto; - -import dev.archie.handymanservice.account.dto.CreatingAccountDto; -import lombok.Data; - -import java.util.Collections; -import java.util.List; - -@Data -public class CreatingHandymanUserDto { - - private String firstName; - - private String lastName; - - private String email; - - private String phone; - - private List accounts; - - private List skills; - - public void setAccounts(List accounts) { - if (accounts == null) { - accounts = Collections.emptyList(); - } - this.accounts = accounts; - } - - public void setSkills(List skills) { - if (skills == null) { - skills = Collections.emptyList(); - } - this.skills = skills; - } -} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/user/exception/HandymanUserAlreadyExistsException.java b/handyman-service/src/main/java/dev/archie/handymanservice/user/exception/HandymanUserAlreadyExistsException.java deleted file mode 100644 index c0618d3..0000000 --- a/handyman-service/src/main/java/dev/archie/handymanservice/user/exception/HandymanUserAlreadyExistsException.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.archie.handymanservice.user.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.web.server.ResponseStatusException; - -public class HandymanUserAlreadyExistsException extends ResponseStatusException { - - public HandymanUserAlreadyExistsException(String email) { - super(HttpStatus.BAD_REQUEST, "HandymanUser with such email already exists: " + email); - } -} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/user/skill/Skill.java b/handyman-service/src/main/java/dev/archie/handymanservice/user/skill/Skill.java deleted file mode 100644 index 01b7cf9..0000000 --- a/handyman-service/src/main/java/dev/archie/handymanservice/user/skill/Skill.java +++ /dev/null @@ -1,43 +0,0 @@ -package dev.archie.handymanservice.user.skill; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import dev.archie.handymanservice.user.HandymanUser; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -@Builder(toBuilder = true) -@AllArgsConstructor -@NoArgsConstructor -@Getter -@Setter -@Entity -@Table(name = "skill") -public class Skill { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id", nullable = false) - private Long id; - - @Column(name = "name") - private String name; - - @JsonIgnoreProperties("skills") - @ManyToOne(cascade = CascadeType.REMOVE) - @JoinColumn(name = "handyman_user_id") - private HandymanUser handymanUser; - -} diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/user/skill/SkillRepository.java b/handyman-service/src/main/java/dev/archie/handymanservice/user/skill/SkillRepository.java deleted file mode 100644 index 219500c..0000000 --- a/handyman-service/src/main/java/dev/archie/handymanservice/user/skill/SkillRepository.java +++ /dev/null @@ -1,6 +0,0 @@ -package dev.archie.handymanservice.user.skill; - -import org.springframework.data.jpa.repository.JpaRepository; - -public interface SkillRepository extends JpaRepository { -} diff --git a/handyman-service/src/main/resources/db/changelog/db.changelog-master.yml b/handyman-service/src/main/resources/db/changelog/db.changelog-master.yml deleted file mode 100644 index ed7bd77..0000000 --- a/handyman-service/src/main/resources/db/changelog/db.changelog-master.yml +++ /dev/null @@ -1,7 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 1 - author: dkutuzov - changes: - - createCollection: - collectionName: users \ No newline at end of file diff --git a/handyman-service/src/main/resources/db/changelog/db.changelog-mongo.yaml b/handyman-service/src/main/resources/db/changelog/db.changelog-mongo.yaml deleted file mode 100644 index ed7bd77..0000000 --- a/handyman-service/src/main/resources/db/changelog/db.changelog-mongo.yaml +++ /dev/null @@ -1,7 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 1 - author: dkutuzov - changes: - - createCollection: - collectionName: users \ No newline at end of file diff --git a/handyman-service/src/test/java/dev/archie/handymanservice/integration/handyman/HandymanControllerTest.java b/handyman-service/src/test/java/dev/archie/handymanservice/integration/handyman/HandymanControllerTest.java deleted file mode 100644 index 4763638..0000000 --- a/handyman-service/src/test/java/dev/archie/handymanservice/integration/handyman/HandymanControllerTest.java +++ /dev/null @@ -1,148 +0,0 @@ -package dev.archie.handymanservice.integration.handyman; - -import dev.archie.handymanservice.handyman.Handyman; -import dev.archie.handymanservice.handyman.Profile; -import dev.archie.handymanservice.handyman.dto.CreatingHandymanDto; -import dev.archie.handymanservice.integration.common.AbstractIntegrationTest; -import dev.archie.handymanservice.landscape.LandscapeService; -import dev.archie.handymanservice.landscape.User; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.mockito.Mockito; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; - -import java.nio.charset.StandardCharsets; -import java.util.List; - -@TestMethodOrder(value = MethodOrderer.OrderAnnotation.class) -@AutoConfigureMockMvc -public class HandymanControllerTest extends AbstractIntegrationTest { - - @MockBean - private LandscapeService landscapeService; - - @Autowired - private MockMvc mockMvc; - - @BeforeEach - void setUp() { - Mockito.when(landscapeService.createUser(Mockito.any())).thenReturn(HandymanConstants.MOCK_RESPONSE_USER); - Mockito.when(landscapeService.getById(Mockito.any())).thenReturn(HandymanConstants.MOCK_RESPONSE_USER); - Mockito.when(landscapeService.update(Mockito.any(), Mockito.any())).thenReturn(HandymanConstants.MOCK_RESPONSE_USER); - } - - @Test - @Order(1) - void postHandymenShouldCreateNewHandyman() throws Exception { - String creatingProfileDtoSerialized = objectMapper.writeValueAsString(HandymanConstants.CREATING_PROFILE_DTO); - String responseSerialized = mockMvc.perform(MockMvcRequestBuilders.post("/handymen") - .contentType(MediaType.APPLICATION_JSON) - .content(creatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Profile actualProfile = objectMapper.readValue(responseSerialized, Profile.class); - User rancher = actualProfile.getUser(); - Handyman handyman = actualProfile.getHandyman(); - Assertions.assertEquals(HandymanConstants.MOCK_RESPONSE_USER, rancher); - Assertions.assertEquals(HandymanConstants.MOCK_RESPONSE_USER.getLongitude(), handyman.getLongitude()); - Assertions.assertEquals(HandymanConstants.MOCK_RESPONSE_USER.getLatitude(), handyman.getLatitude()); - Assertions.assertEquals(HandymanConstants.CREATING_PROFILE_DTO.getSkills(), handyman.getSkills()); - } - - @Test - @Order(2) - void getHandymenShouldReturnExistingUser() throws Exception { - String creatingProfileDtoSerialized = objectMapper.writeValueAsString(HandymanConstants.CREATING_PROFILE_DTO); - String responseSerialized = mockMvc.perform(MockMvcRequestBuilders.post("/handymen") - .contentType(MediaType.APPLICATION_JSON) - .content(creatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Profile existingUser = objectMapper.readValue(responseSerialized, Profile.class); - Handyman existingHandyman = existingUser.getHandyman(); - - - String responseHandymanSerialized = mockMvc.perform(MockMvcRequestBuilders.get("/handymen/" + existingHandyman.getId()) - .contentType(MediaType.APPLICATION_JSON) - .content(creatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Profile handymanSerialized = objectMapper.readValue(responseHandymanSerialized, Profile.class); - Handyman actualHandyman = handymanSerialized.getHandyman(); - Assertions.assertEquals(existingHandyman, actualHandyman); - } - - @Test - @Order(3) - void putHandymenShouldUpdateUser() throws Exception { - String creatingProfileDtoSerialized = objectMapper.writeValueAsString(HandymanConstants.CREATING_PROFILE_DTO); - String responseSerialized = mockMvc.perform(MockMvcRequestBuilders.post("/handymen") - .contentType(MediaType.APPLICATION_JSON) - .content(creatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Profile existingUser = objectMapper.readValue(responseSerialized, Profile.class); - Handyman existingHandyman = existingUser.getHandyman(); - - CreatingHandymanDto updatingUserDto = HandymanConstants.CREATING_PROFILE_DTO.toBuilder().build(); - updatingUserDto.setSkills(List.of("skill3")); - String serializedUpdatingUserDto = objectMapper.writeValueAsString(updatingUserDto); - - String updatedUserSerialized = mockMvc.perform(MockMvcRequestBuilders.put("/handymen/" + existingHandyman.getId()) - .contentType(MediaType.APPLICATION_JSON) - .content(serializedUpdatingUserDto)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - - Profile updatedProfile = objectMapper.readValue(updatedUserSerialized, Profile.class); - Handyman updatedHandyman = updatedProfile.getHandyman(); - - Assertions.assertEquals(updatingUserDto.getSkills(), updatedHandyman.getSkills()); - Assertions.assertEquals(existingHandyman.getInnerId(), updatedHandyman.getInnerId()); - Assertions.assertEquals(existingHandyman.getLongitude(), updatedHandyman.getLongitude()); - Assertions.assertEquals(existingHandyman.getLatitude(), updatedHandyman.getLatitude()); - Assertions.assertEquals(existingHandyman.getId(), updatedHandyman.getId()); - } - - @Test - @Order(4) - void deleteHandymenShouldDeleteExistingUser() throws Exception { - String creatingProfileDtoSerialized = objectMapper.writeValueAsString(HandymanConstants.CREATING_PROFILE_DTO); - String responseSerialized = mockMvc.perform(MockMvcRequestBuilders.post("/handymen") - .contentType(MediaType.APPLICATION_JSON) - .content(creatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Profile existingUser = objectMapper.readValue(responseSerialized, Profile.class); - Handyman existingHandyman = existingUser.getHandyman(); - - mockMvc.perform(MockMvcRequestBuilders.delete("/handymen/" + existingHandyman.getId())) - .andExpect(MockMvcResultMatchers.status().isOk()); - - Mockito.verify(landscapeService, Mockito.times(1)).delete(Mockito.any()); - } - - -} diff --git a/landscape-service/build.gradle b/landscape-service/build.gradle index 3ae0d2a..bbeb5fd 100644 --- a/landscape-service/build.gradle +++ b/landscape-service/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.springframework.boot' version '2.7.8' + id 'org.springframework.boot' version '2.7.13' id 'io.spring.dependency-management' version '1.0.15.RELEASE' id 'java-library' id 'com.google.protobuf' version '0.9.2' diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/LandscapeConfiguration.java b/landscape-service/src/main/java/dev/archie/landscapeservice/LandscapeConfiguration.java new file mode 100644 index 0000000..a557338 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/LandscapeConfiguration.java @@ -0,0 +1,15 @@ +package dev.archie.landscapeservice; + +import org.n52.jackson.datatype.jts.JtsModule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class LandscapeConfiguration { + + @Bean + public JtsModule jtsModule() { + return new JtsModule(); + } + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/account/Account.java b/landscape-service/src/main/java/dev/archie/landscapeservice/account/Account.java index 393fc8f..01ce89c 100644 --- a/landscape-service/src/main/java/dev/archie/landscapeservice/account/Account.java +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/account/Account.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import dev.archie.landscapeservice.account.bank.Bank; +import dev.archie.landscapeservice.handyman.Handyman; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -37,11 +38,6 @@ public class Account { @Column(name = "card_number") private String cardNumber; - @JsonIgnoreProperties("accounts") - @ManyToOne - @JoinColumn(name = "handyman_user_id") - private HandymanUser handymanUser; - @Enumerated(EnumType.STRING) @Column(name = "payment_system") private PaymentSystem paymentSystem; @@ -50,6 +46,11 @@ public class Account { @JoinColumn(name = "bank_id") private Bank bank; + @ManyToOne + @JoinColumn(name = "handyman_id") + @JsonIgnoreProperties("accounts") + private Handyman handyman; + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/account/AccountController.java b/landscape-service/src/main/java/dev/archie/landscapeservice/account/AccountController.java new file mode 100644 index 0000000..4f29320 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/account/AccountController.java @@ -0,0 +1,45 @@ +package dev.archie.landscapeservice.account; + +import dev.archie.landscapeservice.account.dto.CreatingAccountDto; +import lombok.RequiredArgsConstructor; +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; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.UUID; + +@RestController +@RequestMapping("/accounts") +@RequiredArgsConstructor +public class AccountController { + + private final AccountService accountService; + + @PostMapping("/{handymanId}") + public Account create(@RequestBody CreatingAccountDto creatingAccountDto, + @PathVariable UUID handymanId) { + return accountService.create(creatingAccountDto, handymanId); + } + + @PutMapping("/{accountId}") + public Account update(@RequestBody CreatingAccountDto creatingAccountDto, + @PathVariable Long accountId) { + return accountService.update(creatingAccountDto, accountId); + } + + @GetMapping("/{accountId}") + public Account getById(@PathVariable Long accountId) { + return accountService.getById(accountId); + } + + @DeleteMapping("/{accountId}") + public void delete(@PathVariable Long accountId) { + accountService.delete(accountId); + } + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/account/AccountRepository.java b/landscape-service/src/main/java/dev/archie/landscapeservice/account/AccountRepository.java new file mode 100644 index 0000000..286fa0d --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/account/AccountRepository.java @@ -0,0 +1,6 @@ +package dev.archie.landscapeservice.account; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AccountRepository extends JpaRepository { +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/account/AccountService.java b/landscape-service/src/main/java/dev/archie/landscapeservice/account/AccountService.java new file mode 100644 index 0000000..ce63e42 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/account/AccountService.java @@ -0,0 +1,59 @@ +package dev.archie.landscapeservice.account; + +import dev.archie.landscapeservice.account.bank.BankService; +import dev.archie.landscapeservice.account.dto.CreatingAccountDto; +import dev.archie.landscapeservice.account.exception.NoSuchAccountException; +import dev.archie.landscapeservice.handyman.Handyman; +import dev.archie.landscapeservice.handyman.HandymanRepository; +import dev.archie.landscapeservice.user.exceptions.NoSuchUserException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class AccountService { + + private final AccountRepository accountRepository; + private final HandymanRepository handymanUserRepository; + private final BankService bankService; + + public Account create(CreatingAccountDto accountDto, UUID handymanUserId) { + Handyman user = getHandymanById(handymanUserId); + Account account = mapCreatingAccountDtoToAccount(accountDto, user); + account.setBank(bankService.getBankByName(accountDto.getBankName())); + return accountRepository.save(account); + } + + public Account getById(Long id) { + return accountRepository.findById(id) + .orElseThrow(() -> new NoSuchAccountException(id)); + } + + public Account update(CreatingAccountDto accountDto, Long id) { + Account account = getById(id); + Account updatedAccount = mapCreatingAccountDtoToAccount(accountDto, account.getHandyman()); + account.setBank(bankService.getBankByName(accountDto.getBankName())); + updatedAccount.setId(id); + return accountRepository.save(updatedAccount); + } + + public void delete(Long id) { + accountRepository.delete(getById(id)); + } + + private Handyman getHandymanById(UUID handymanUserId) { + return handymanUserRepository.findById(handymanUserId) + .orElseThrow(() -> new NoSuchUserException(handymanUserId)); + } + + private Account mapCreatingAccountDtoToAccount(CreatingAccountDto accountDto, Handyman user) { + return Account.builder() + .handyman(user) + .cardNumber(accountDto.getCardNumber()) + .paymentSystem(accountDto.getPaymentSystem()) + .build(); + } + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/account/HandymanUser.java b/landscape-service/src/main/java/dev/archie/landscapeservice/account/HandymanUser.java deleted file mode 100644 index a667a65..0000000 --- a/landscape-service/src/main/java/dev/archie/landscapeservice/account/HandymanUser.java +++ /dev/null @@ -1,61 +0,0 @@ -package dev.archie.landscapeservice.account; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import dev.archie.landscapeservice.account.skill.Skill; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.hibernate.annotations.Type; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import java.util.List; - - -@Builder(toBuilder = true) -@AllArgsConstructor -@NoArgsConstructor -@Getter -@Setter -@Entity -@Table(name = "handyman_user") -public class HandymanUser { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id", nullable = false) - private Long id; - - @Column(name = "first_name", nullable = false) - private String firstName; - - @Column(name = "last_name", nullable = false) - private String lastName; - - @Column(name = "email", nullable = false) - private String email; - - @Column(name = "phone") - private String phone; - - @Type(type="org.hibernate.type.BinaryType") - @Column(name = "photo") - private byte[] photo; - - @JsonIgnoreProperties("handymanUser") - @OneToMany(mappedBy = "handymanUser", cascade = CascadeType.REMOVE, orphanRemoval = true) - private List accounts; - - @JsonIgnoreProperties("handymanUser") - @OneToMany(mappedBy = "handymanUser", cascade = CascadeType.REMOVE, orphanRemoval = true) - private List skills; - -} \ No newline at end of file diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/account/bank/BankRepository.java b/landscape-service/src/main/java/dev/archie/landscapeservice/account/bank/BankRepository.java index 4ac0822..c20c566 100644 --- a/landscape-service/src/main/java/dev/archie/landscapeservice/account/bank/BankRepository.java +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/account/bank/BankRepository.java @@ -12,7 +12,7 @@ public interface BankRepository extends JpaRepository { @Query(""" select new dev.archie.landscapeservice.stat.BankStat(a.bank.name, min(u.createdAt), max(u.createdAt)) - from Account a join User u on a.handymanUser.email = u.email + from Account a join User u on a.handyman.email = u.email group by a.bank.name """) List findAllBankStat(); diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/account/bank/BankService.java b/landscape-service/src/main/java/dev/archie/landscapeservice/account/bank/BankService.java new file mode 100644 index 0000000..f1461c9 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/account/bank/BankService.java @@ -0,0 +1,18 @@ +package dev.archie.landscapeservice.account.bank; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +@Service +@RequiredArgsConstructor +public class BankService { + private final BankRepository bankRepository; + + public Bank getBankByName(String bankName) { + return bankRepository.findByName(bankName) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, + "No such bank with name " + bankName)); + } +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/account/dto/CreatingAccountDto.java b/landscape-service/src/main/java/dev/archie/landscapeservice/account/dto/CreatingAccountDto.java new file mode 100644 index 0000000..e9da5db --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/account/dto/CreatingAccountDto.java @@ -0,0 +1,14 @@ +package dev.archie.landscapeservice.account.dto; + +import dev.archie.landscapeservice.account.PaymentSystem; +import lombok.Data; + +@Data +public class CreatingAccountDto { + + private String cardNumber; + + private PaymentSystem paymentSystem; + + private String bankName; +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/account/exception/NoSuchAccountException.java b/landscape-service/src/main/java/dev/archie/landscapeservice/account/exception/NoSuchAccountException.java new file mode 100644 index 0000000..2448d14 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/account/exception/NoSuchAccountException.java @@ -0,0 +1,11 @@ +package dev.archie.landscapeservice.account.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; + +public class NoSuchAccountException extends ResponseStatusException { + + public NoSuchAccountException(Long id) { + super(HttpStatus.NOT_FOUND, "No such account with id: " + id); + } +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/account/skill/Skill.java b/landscape-service/src/main/java/dev/archie/landscapeservice/account/skill/Skill.java index aaa754e..309f680 100644 --- a/landscape-service/src/main/java/dev/archie/landscapeservice/account/skill/Skill.java +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/account/skill/Skill.java @@ -1,14 +1,13 @@ package dev.archie.landscapeservice.account.skill; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import dev.archie.landscapeservice.account.HandymanUser; +import dev.archie.landscapeservice.handyman.Handyman; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -35,9 +34,9 @@ public class Skill { @Column(name = "name") private String name; + @ManyToOne + @JoinColumn(name = "handyman_id") @JsonIgnoreProperties("skills") - @ManyToOne(cascade = CascadeType.REMOVE) - @JoinColumn(name = "handyman_user_id") - private HandymanUser handymanUser; + private Handyman handyman; } diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/field/Field.java b/landscape-service/src/main/java/dev/archie/landscapeservice/field/Field.java index d75d58b..ab6f22e 100644 --- a/landscape-service/src/main/java/dev/archie/landscapeservice/field/Field.java +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/field/Field.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import dev.archie.landscapeservice.stat.Gardener; +import dev.archie.landscapeservice.gardener.Gardener; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -45,7 +45,6 @@ public class Field { @JsonSerialize(using = GeometrySerializer.class) @JsonDeserialize(contentUsing = GeometryDeserializer.class) - @Column(name = "area", columnDefinition = "geometry(Point, 4326)", nullable = false) private Geometry area; @ManyToOne diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/field/FieldController.java b/landscape-service/src/main/java/dev/archie/landscapeservice/field/FieldController.java new file mode 100644 index 0000000..7b41a70 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/field/FieldController.java @@ -0,0 +1,43 @@ +package dev.archie.landscapeservice.field; + +import dev.archie.landscapeservice.field.dto.CreatingFieldDto; +import lombok.RequiredArgsConstructor; +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; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.UUID; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/fields") +public class FieldController { + + private final FieldService fieldService; + + @PostMapping("/{gardenerId}") + public Field create(@RequestBody CreatingFieldDto creatingFieldDto, @PathVariable UUID gardenerId) { + return fieldService.create(creatingFieldDto, gardenerId); + } + + @GetMapping("/{id}") + public Field getById(@PathVariable Long id) { + return fieldService.getById(id); + } + + @PutMapping("/{id}") + public Field update(@RequestBody CreatingFieldDto creatingFieldDto, @PathVariable Long id) { + return fieldService.update(creatingFieldDto, id); + } + + @DeleteMapping("/{id}") + public void delete(@PathVariable Long id) { + fieldService.delete(id); + } + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/field/FieldService.java b/landscape-service/src/main/java/dev/archie/landscapeservice/field/FieldService.java index 5b90b9b..cc7bb40 100644 --- a/landscape-service/src/main/java/dev/archie/landscapeservice/field/FieldService.java +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/field/FieldService.java @@ -1,18 +1,51 @@ package dev.archie.landscapeservice.field; +import dev.archie.landscapeservice.field.dto.CreatingFieldDto; import dev.archie.landscapeservice.field.exceptions.FieldDoesNotExistsException; +import dev.archie.landscapeservice.gardener.Gardener; +import dev.archie.landscapeservice.gardener.GardenerService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.UUID; + @Service @RequiredArgsConstructor public class FieldService { private final FieldRepository fieldRepository; + private final GardenerService gardenerService; + + public Field create(CreatingFieldDto fieldDto, UUID gardenerId) { + Gardener gardener = gardenerService.getById(gardenerId); + Field field = mapCreatingFieldDtoToField(fieldDto, gardener); + return fieldRepository.save(field); + } public Field getById(Long id) { return fieldRepository.findById(id) .orElseThrow(() -> new FieldDoesNotExistsException(id)); } + public Field update(CreatingFieldDto fieldDto, Long id) { + Field field = getById(id); + Field updatedField = mapCreatingFieldDtoToField(fieldDto, field.getGardener()); + updatedField.setId(field.getId()); + return fieldRepository.save(updatedField); + } + + public void delete(Long id) { + fieldRepository.delete(getById(id)); + } + + private Field mapCreatingFieldDtoToField(CreatingFieldDto fieldDto, Gardener gardener) { + return Field.builder() + .latitude(fieldDto.getLatitude()) + .longitude(fieldDto.getLongitude()) + .address(fieldDto.getAddress()) + .gardener(gardener) + .area(fieldDto.getArea()) + .build(); + } + } diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/field/dto/CreatingFieldDto.java b/landscape-service/src/main/java/dev/archie/landscapeservice/field/dto/CreatingFieldDto.java new file mode 100644 index 0000000..13d3f64 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/field/dto/CreatingFieldDto.java @@ -0,0 +1,23 @@ +package dev.archie.landscapeservice.field.dto; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Data; +import org.locationtech.jts.geom.Geometry; +import org.n52.jackson.datatype.jts.GeometryDeserializer; +import org.n52.jackson.datatype.jts.GeometrySerializer; + +import java.util.List; + +@Data +public class CreatingFieldDto { + private Double latitude; + private Double longitude; + private Double fieldArea; + private List jobs; + private String address; + + @JsonSerialize(using = GeometrySerializer.class) + @JsonDeserialize(contentUsing = GeometryDeserializer.class) + private Geometry area; +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/Gardener.java b/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/Gardener.java new file mode 100644 index 0000000..0bffc78 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/Gardener.java @@ -0,0 +1,32 @@ +package dev.archie.landscapeservice.gardener; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import dev.archie.landscapeservice.field.Field; +import dev.archie.landscapeservice.user.User; +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.util.List; + +@Getter +@Setter +@Entity +@Table(name = "gardener") +public class Gardener extends User { + + @JsonIgnoreProperties(value = "gardener") + @OneToMany(mappedBy = "gardener", cascade = CascadeType.REMOVE, orphanRemoval = true) + private List fields; + + @JsonSetter(nulls = Nulls.AS_EMPTY) + public void setFields(List fields) { + this.fields = fields; + } + +} \ No newline at end of file diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/GardenerController.java b/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/GardenerController.java new file mode 100644 index 0000000..1545dcb --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/GardenerController.java @@ -0,0 +1,44 @@ +package dev.archie.landscapeservice.gardener; + +import dev.archie.landscapeservice.gardener.dto.CreatingGardenerDto; +import lombok.RequiredArgsConstructor; +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; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.UUID; + +@RestController +@RequestMapping("/gardeners") +@RequiredArgsConstructor +public class GardenerController { + + private final GardenerService gardenerService; + + @PostMapping + public Gardener create(@RequestBody CreatingGardenerDto creatingGardenerDto) { + return gardenerService.create(creatingGardenerDto); + } + + @GetMapping("/{id}") + public Gardener getById(@PathVariable UUID id) { + return gardenerService.getById(id); + } + + @PutMapping("/{id}") + public Gardener update(@PathVariable UUID id, + @RequestBody CreatingGardenerDto creatingGardenerDto) { + return gardenerService.update(creatingGardenerDto, id); + } + + @DeleteMapping("/{id}") + public void delete(@PathVariable UUID id) { + gardenerService.delete(id); + } + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/GardenerRepository.java b/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/GardenerRepository.java new file mode 100644 index 0000000..45556d1 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/GardenerRepository.java @@ -0,0 +1,8 @@ +package dev.archie.landscapeservice.gardener; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.UUID; + +public interface GardenerRepository extends JpaRepository { +} \ No newline at end of file diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/GardenerService.java b/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/GardenerService.java new file mode 100644 index 0000000..88ada14 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/GardenerService.java @@ -0,0 +1,63 @@ +package dev.archie.landscapeservice.gardener; + +import dev.archie.landscapeservice.gardener.dto.CreatingGardenerDto; +import dev.archie.landscapeservice.user.exceptions.NoSuchUserException; +import dev.archie.landscapeservice.user.type.UserType; +import dev.archie.landscapeservice.user.type.UserTypeRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class GardenerService { + + private final GardenerRepository gardenerRepository; + private final UserTypeRepository userTypeRepository; + + public Gardener create(CreatingGardenerDto gardenerDto) { + Gardener gardener = mapCreatingGardenerDtoToGardener(gardenerDto); + gardener.setCreatedAt(LocalDateTime.now()); + gardener.setLastUpdatedAt(LocalDateTime.now()); + return gardenerRepository.save(gardener); + } + + public Gardener getById(UUID id) { + return gardenerRepository.findById(id) + .orElseThrow(() -> new NoSuchUserException(id)); + } + + public Gardener update(CreatingGardenerDto creatingGardenerDto, UUID id) { + Gardener gardener = getById(id); + Gardener updated = mapCreatingGardenerDtoToGardener(creatingGardenerDto); + gardener.setEmail(updated.getEmail()); + gardener.setLogin(updated.getLogin()); + gardener.setLatitude(updated.getLatitude()); + gardener.setLongitude(updated.getLongitude()); + gardener.setPhoneNumber(updated.getPhoneNumber()); + gardener.setLastName(updated.getLastName()); + gardener.setFirstName(updated.getFirstName()); + gardener.setLastUpdatedAt(LocalDateTime.now()); + return gardenerRepository.save(gardener); + } + + public void delete(UUID id) { + gardenerRepository.delete(getById(id)); + } + + private Gardener mapCreatingGardenerDtoToGardener(CreatingGardenerDto gardenerDto) { + Gardener gardener = new Gardener(); + gardener.setEmail(gardenerDto.getEmail()); + gardener.setLogin(gardenerDto.getLogin()); + gardener.setLatitude(gardenerDto.getLatitude()); + gardener.setLongitude(gardenerDto.getLongitude()); + gardener.setUserType(userTypeRepository.findById(UserType.RANCHER_USER_TYPE_ID).get()); + gardener.setPhoneNumber(gardenerDto.getPhone()); + gardener.setLastName(gardenerDto.getLastName()); + gardener.setFirstName(gardenerDto.getFirstName()); + return gardener; + } + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/dto/CreatingGardenerDto.java b/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/dto/CreatingGardenerDto.java new file mode 100644 index 0000000..a845c9a --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/gardener/dto/CreatingGardenerDto.java @@ -0,0 +1,24 @@ +package dev.archie.landscapeservice.gardener.dto; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder(toBuilder = true) +public class CreatingGardenerDto { + + private String login; + + private String email; + + private String phone; + + private String firstName; + + private String lastName; + + private Double latitude; + + private Double longitude; + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/Handyman.java b/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/Handyman.java new file mode 100644 index 0000000..2010ded --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/Handyman.java @@ -0,0 +1,35 @@ +package dev.archie.landscapeservice.handyman; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import dev.archie.landscapeservice.account.Account; +import dev.archie.landscapeservice.account.skill.Skill; +import dev.archie.landscapeservice.user.User; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.Type; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +@Entity +@Table(name = "handyman_user") +public class Handyman extends User { + + @Type(type="org.hibernate.type.BinaryType") + private byte[] photo; + + @OneToMany(mappedBy = "handyman", cascade = CascadeType.REMOVE, orphanRemoval = true) + @JsonIgnoreProperties("handyman") + private List accounts = new ArrayList<>(); + + @OneToMany(mappedBy = "handyman", cascade = CascadeType.REMOVE, orphanRemoval = true) + @JsonIgnoreProperties("handyman") + private List skills = new ArrayList<>(); + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/HandymanController.java b/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/HandymanController.java new file mode 100644 index 0000000..de25ae0 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/HandymanController.java @@ -0,0 +1,43 @@ +package dev.archie.landscapeservice.handyman; + +import dev.archie.landscapeservice.handyman.dto.CreatingHandymanDto; +import lombok.RequiredArgsConstructor; +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; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.UUID; + +@RestController +@RequestMapping("/handymen") +@RequiredArgsConstructor +public class HandymanController { + + private final HandymanService handymanService; + + @PostMapping + public Handyman create(@RequestBody CreatingHandymanDto creatingHandymanDto) { + return handymanService.create(creatingHandymanDto); + } + + @GetMapping("/{id}") + public Handyman getById(@PathVariable UUID id) { + return handymanService.getById(id); + } + + @PutMapping("/{id}") + public Handyman update(@PathVariable UUID id, @RequestBody CreatingHandymanDto creatingHandymanDto) { + return handymanService.update(creatingHandymanDto, id); + } + + @DeleteMapping("/{id}") + public void delete(@PathVariable UUID id) { + handymanService.delete(id); + } + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/HandymanRepository.java b/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/HandymanRepository.java new file mode 100644 index 0000000..ab0696f --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/HandymanRepository.java @@ -0,0 +1,8 @@ +package dev.archie.landscapeservice.handyman; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.UUID; + +public interface HandymanRepository extends JpaRepository { +} \ No newline at end of file diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/HandymanService.java b/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/HandymanService.java new file mode 100644 index 0000000..1f608a0 --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/HandymanService.java @@ -0,0 +1,63 @@ +package dev.archie.landscapeservice.handyman; + +import dev.archie.landscapeservice.handyman.dto.CreatingHandymanDto; +import dev.archie.landscapeservice.user.exceptions.NoSuchUserException; +import dev.archie.landscapeservice.user.type.UserType; +import dev.archie.landscapeservice.user.type.UserTypeRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class HandymanService { + + private final HandymanRepository handymanRepository; + private final UserTypeRepository userTypeRepository; + + public Handyman create(CreatingHandymanDto creatingHandymanDto) { + Handyman handyman = mapCreatingHandymanDtoToHandyman(creatingHandymanDto); + handyman.setCreatedAt(LocalDateTime.now()); + handyman.setLastUpdatedAt(LocalDateTime.now()); + return handymanRepository.save(handyman); + } + + public Handyman getById(UUID id) { + return handymanRepository.findById(id) + .orElseThrow(() -> new NoSuchUserException(id)); + } + + public Handyman update(CreatingHandymanDto handymanDto, UUID id) { + Handyman handyman = getById(id); + Handyman updated = mapCreatingHandymanDtoToHandyman(handymanDto); + handyman.setEmail(updated.getEmail()); + handyman.setFirstName(updated.getFirstName()); + handyman.setLastName(updated.getLastName()); + handyman.setLatitude(updated.getLatitude()); + handyman.setLongitude(updated.getLongitude()); + handyman.setLogin(updated.getLogin()); + handyman.setPhoneNumber(updated.getPhoneNumber()); + handyman.setLastUpdatedAt(LocalDateTime.now()); + return handymanRepository.save(handyman); + } + + public void delete(UUID id) { + handymanRepository.delete(getById(id)); + } + + private Handyman mapCreatingHandymanDtoToHandyman(CreatingHandymanDto creatingHandymanDto) { + Handyman handyman = new Handyman(); + handyman.setEmail(creatingHandymanDto.getEmail()); + handyman.setFirstName(creatingHandymanDto.getFirstName()); + handyman.setLastName(creatingHandymanDto.getLastName()); + handyman.setLatitude(creatingHandymanDto.getLatitude()); + handyman.setLongitude(creatingHandymanDto.getLongitude()); + handyman.setLogin(creatingHandymanDto.getLogin()); + handyman.setUserType(userTypeRepository.findById(UserType.HANDYMAN_USER_TYPE_ID).get()); + handyman.setPhoneNumber(creatingHandymanDto.getPhoneNumber()); + return handyman; + } + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/dto/CreatingHandymanDto.java b/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/dto/CreatingHandymanDto.java new file mode 100644 index 0000000..400507c --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/handyman/dto/CreatingHandymanDto.java @@ -0,0 +1,26 @@ +package dev.archie.landscapeservice.handyman.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class CreatingHandymanDto { + + private String login; + + private String email; + + private String phoneNumber; + + private Double latitude; + + private Double longitude; + + private List skills; + + private String firstName; + + private String lastName; + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/order/OrderRepository.java b/landscape-service/src/main/java/dev/archie/landscapeservice/order/OrderRepository.java index b3b61b8..87e4fd9 100644 --- a/landscape-service/src/main/java/dev/archie/landscapeservice/order/OrderRepository.java +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/order/OrderRepository.java @@ -1,12 +1,41 @@ package dev.archie.landscapeservice.order; +import dev.archie.landscapeservice.handyman.Handyman; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import java.util.List; import java.util.UUID; public interface OrderRepository extends JpaRepository { Page findByUser_IdOrderByUser_LoginDesc(UUID id, Pageable pageable); + Page findByUser_IdOrderByUser_LoginAsc(UUID id, Pageable pageable); + + @Query(""" + select distinct o.workType + from Order o + where o.field.id = ?1 + """) + List findDistinctByField_Id(Long id); + + @Query(""" + SELECT h + FROM Order o JOIN o.user u + JOIN Handyman h ON u.id = h.id + WHERE o.field.id = ?1 + """) + List findHandymenByField_Id(Long id); + + @Query(""" + SELECT COUNT(DISTINCT s) < COUNT(DISTINCT o.workType) + FROM Order o JOIN o.user u + JOIN Handyman h ON u.id = h.id + JOIN h.skills s + JOIN o.field f + WHERE f.id = ?1 + """) + Boolean isWorkDeficit(Long id); } \ No newline at end of file diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/report/Report.java b/landscape-service/src/main/java/dev/archie/landscapeservice/report/Report.java new file mode 100644 index 0000000..5f60d1c --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/report/Report.java @@ -0,0 +1,14 @@ +package dev.archie.landscapeservice.report; + +import dev.archie.landscapeservice.handyman.Handyman; +import dev.archie.landscapeservice.order.WorkType; +import lombok.Data; + +import java.util.List; + +@Data +public class Report { + List works; + List workers; + Boolean isWorkDeficit; +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/report/ReportController.java b/landscape-service/src/main/java/dev/archie/landscapeservice/report/ReportController.java new file mode 100644 index 0000000..80b340b --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/report/ReportController.java @@ -0,0 +1,19 @@ +package dev.archie.landscapeservice.report; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/reports") +public class ReportController { + private final ReportService reportService; + + @GetMapping("/{fieldId}") + public Report getReportByFieldId(@PathVariable Long fieldId) { + return reportService.getReport(fieldId); + } +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/report/ReportService.java b/landscape-service/src/main/java/dev/archie/landscapeservice/report/ReportService.java new file mode 100644 index 0000000..5fda86e --- /dev/null +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/report/ReportService.java @@ -0,0 +1,22 @@ +package dev.archie.landscapeservice.report; + +import dev.archie.landscapeservice.order.OrderRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j +public class ReportService { + private final OrderRepository orderRepository; + + public Report getReport(Long fieldId) { + Report report = new Report(); + report.setWorks(orderRepository.findDistinctByField_Id(fieldId)); + report.setWorkers(orderRepository.findHandymenByField_Id(fieldId)); + report.setIsWorkDeficit(orderRepository.isWorkDeficit(fieldId)); + return report; + } + +} diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/stat/Gardener.java b/landscape-service/src/main/java/dev/archie/landscapeservice/stat/Gardener.java deleted file mode 100644 index ea021c6..0000000 --- a/landscape-service/src/main/java/dev/archie/landscapeservice/stat/Gardener.java +++ /dev/null @@ -1,60 +0,0 @@ -package dev.archie.landscapeservice.stat; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; -import dev.archie.landscapeservice.field.Field; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import java.util.List; - -@Builder -@Getter -@Setter -@NoArgsConstructor -@AllArgsConstructor -@Entity -@Table(name = "gardener") -public class Gardener { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "first_name", nullable = false) - private String firstName; - - @Column(name = "login") - private String login; - - @Column(name = "last_name", nullable = false) - private String lastName; - - @Column(name = "email", nullable = false) - private String email; - - @Column(name = "phone") - private String phone; - - @JsonIgnoreProperties(value = "gardener") - @OneToMany(mappedBy = "gardener", cascade = CascadeType.REMOVE, orphanRemoval = true) - private List fields; - - @JsonSetter(nulls = Nulls.AS_EMPTY) - public void setFields(List fields) { - this.fields = fields; - } - -} \ No newline at end of file diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/stat/RancherStat.java b/landscape-service/src/main/java/dev/archie/landscapeservice/stat/RancherStat.java index 7707fd1..32d86ed 100644 --- a/landscape-service/src/main/java/dev/archie/landscapeservice/stat/RancherStat.java +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/stat/RancherStat.java @@ -2,15 +2,17 @@ import lombok.Data; +import java.util.UUID; + @Data public class RancherStat { - private Long gardenerId; + private UUID gardenerId; private String login; private double minPlotSize; private double maxPlotSize; private double averagePlotArea; - public RancherStat(Long gardenerId, String login, double minPlotSize, double maxPlotSize, double averagePlotArea) { + public RancherStat(UUID gardenerId, String login, double minPlotSize, double maxPlotSize, double averagePlotArea) { this.gardenerId = gardenerId; this.login = login; this.minPlotSize = minPlotSize; diff --git a/landscape-service/src/main/java/dev/archie/landscapeservice/user/User.java b/landscape-service/src/main/java/dev/archie/landscapeservice/user/User.java index 6f3a6e1..7f58473 100644 --- a/landscape-service/src/main/java/dev/archie/landscapeservice/user/User.java +++ b/landscape-service/src/main/java/dev/archie/landscapeservice/user/User.java @@ -13,6 +13,8 @@ import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @@ -27,6 +29,7 @@ @Setter @Entity @Table(name = "users") +@Inheritance(strategy = InheritanceType.JOINED) public class User { @Id @@ -60,6 +63,12 @@ public class User { @JoinColumn(name = "user_type_id") private UserType userType; + @Column(name = "first_name") + private String firstName; + + @Column(name = "last_name") + private String lastName; + @Override public boolean equals(Object o) { if (this == o) return true; @@ -73,15 +82,4 @@ public int hashCode() { return getClass().hashCode(); } - @Override - public String toString() { - return getClass().getSimpleName() + "(" + - "id = " + id + ", " + - "login = " + login + ", " + - "email = " + email + ", " + - "phoneNumber = " + phoneNumber + ", " + - "createdAt = " + createdAt + ", " + - "lastUpdatedAt = " + lastUpdatedAt + ", " + - "userType = " + userType + ")"; - } } diff --git a/landscape-service/src/main/resources/application.properties b/landscape-service/src/main/resources/application.properties index 38cd7ee..8822738 100644 --- a/landscape-service/src/main/resources/application.properties +++ b/landscape-service/src/main/resources/application.properties @@ -14,3 +14,6 @@ grpc.client.rancher-service.negotiation-type=plaintext spring.datasource.url=${DB_URL} spring.datasource.username=${DB_USERNAME} spring.datasource.password=${DB_PASSWORD} + +spring.jpa.hibernate.ddl-auto=update +spring.liquibase.enabled=true \ No newline at end of file diff --git a/landscape-service/src/main/resources/db/changelog/db.changelog-master.yaml b/landscape-service/src/main/resources/db/changelog/db.changelog-master.yaml index a435c70..ad09938 100644 --- a/landscape-service/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/landscape-service/src/main/resources/db/changelog/db.changelog-master.yaml @@ -1,19 +1,3 @@ databaseChangeLog: - include: - file: db/hw5/2023-03-15--01-create-user-table.sql - - include: - file: db/hw5/2023-03-15--02-alter-user-table.sql - - changeSet: - id: 3 - author: dkutuzov - changes: - - sqlFile: - dbms: postgresql - splitStatements: false - path: db/hw5/2023-03-15--03-procedure-update-user-type.sql - - include: - file: db/hw5/2023-04-06--04-add-coordinates.sql - - include: - file: db/hw8/2023-05-09--05-add-order-table.sql - - include: - file: db/hw9/2023-06-14--06-add-login-to-gardener.sql + file: db/hw11/2023-06-23--07-add-uuid.sql \ No newline at end of file diff --git a/landscape-service/src/main/resources/db/hw11/2023-06-23--07-add-uuid.sql b/landscape-service/src/main/resources/db/hw11/2023-06-23--07-add-uuid.sql new file mode 100644 index 0000000..dab0813 --- /dev/null +++ b/landscape-service/src/main/resources/db/hw11/2023-06-23--07-add-uuid.sql @@ -0,0 +1,14 @@ +--liquibase formatted sql + +--changeset dkutuzov:7 +create extension if not exists "uuid-ossp"; + +create table if not exists user_types +( + id smallserial primary key, + type text not null +); + +insert into user_types(id, type) +values (1, 'rancher'), + (2, 'handyman'); diff --git a/rancher-service/build.gradle b/rancher-service/build.gradle index 7a5eb00..1e8585f 100644 --- a/rancher-service/build.gradle +++ b/rancher-service/build.gradle @@ -17,7 +17,6 @@ plugins { id 'java-library' id 'com.google.protobuf' version "${protobufPluginVersion}" id 'idea' - id 'org.liquibase.gradle' version '2.2.0' } group = 'dev.archie' @@ -73,16 +72,9 @@ dependencies { 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-jpa' - runtimeOnly 'org.postgresql:postgresql' implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' testImplementation "org.testcontainers:mongodb:1.18.0" - liquibaseRuntime 'org.mongodb:bson:4.9.0' - liquibaseRuntime 'org.mongodb:mongodb-driver-core:4.9.0' - liquibaseRuntime 'org.mongodb:mongodb-driver-sync:4.9.0' - liquibaseRuntime 'org.liquibase.ext:liquibase-mongodb:4.20.0' implementation 'org.liquibase:liquibase-core:4.20.0' - liquibaseRuntime 'info.picocli:picocli:4.6.1' implementation 'org.yaml:snakeyaml:2.0' implementation 'org.springframework.boot:spring-boot-starter-web' diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/field/Field.java b/rancher-service/src/main/java/dev/archie/rancherservice/field/Field.java index 9a74e16..789e73f 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/field/Field.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/field/Field.java @@ -1,58 +1,42 @@ package dev.archie.rancherservice.field; -import org.n52.jackson.datatype.jts.GeometryDeserializer; -import org.n52.jackson.datatype.jts.GeometrySerializer; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import dev.archie.rancherservice.gardener.Gardener; +import dev.archie.rancherservice.rancher.Gardener; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import org.locationtech.jts.geom.Geometry; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.DocumentReference; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; +import java.util.List; @Builder @Getter @Setter @NoArgsConstructor @AllArgsConstructor -@Entity -@Table(name = "field") +@Document(collection = "fields") public class Field { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + private String id; - @JsonIgnoreProperties(value = "fields") - @ManyToOne - @JoinColumn(name = "gardener_id", nullable = false) - private Gardener gardener; + private Long innerId; - @Column(name = "address", nullable = false) - private String address; - - @Column(name = "latitude", nullable = false) private Double latitude; - @Column(name = "longitude", nullable = false) private Double longitude; - @JsonSerialize(using = GeometrySerializer.class) - @JsonDeserialize(contentUsing = GeometryDeserializer.class) - @Column(name = "area", columnDefinition = "geometry(Point, 4326)", nullable = false) - private Geometry area; + private Double area; -} + private List jobs; + private String address; + + @JsonIgnoreProperties(value = "fields") + @DocumentReference + private Gardener gardener; +} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldController.java b/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldController.java index 0833370..eb77147 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldController.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldController.java @@ -9,34 +9,34 @@ 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; @RestController -@RequestMapping("fields") +@RequestMapping("/fields") @RequiredArgsConstructor public class FieldController { private final FieldService fieldService; - @PostMapping - public Field create(@RequestBody CreatingFieldDto fieldDto, @RequestParam Long gardenerId) { - return fieldService.create(fieldDto, gardenerId); + @PostMapping("/{gardenerId}") + public Field create(@RequestBody CreatingFieldDto creatingFieldDto, + @PathVariable String gardenerId) { + return fieldService.create(creatingFieldDto, gardenerId); } - @GetMapping("/{id}") - public Field getById(@PathVariable Long id) { - return fieldService.getById(id); + @GetMapping("/{fieldId}") + public Field getById(@PathVariable String fieldId) { + return fieldService.getById(fieldId); } - @PutMapping("/{id}") - public Field update(@RequestBody CreatingFieldDto fieldDto, @PathVariable Long id) { - return fieldService.update(fieldDto, id); + @PutMapping("/{fieldId}") + public Field update(@RequestBody CreatingFieldDto creatingFieldDto, @PathVariable String fieldId) { + return fieldService.update(creatingFieldDto, fieldId); } - @DeleteMapping("/{id}") - public void delete(@PathVariable Long id) { - fieldService.delete(id); + @DeleteMapping("/{fieldId}") + public void delete(@PathVariable String fieldId) { + fieldService.delete(fieldId); } } diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldMapper.java b/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldMapper.java deleted file mode 100644 index eddbae6..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldMapper.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.archie.rancherservice.field; - -import dev.archie.rancherservice.field.dto.CreatingFieldDto; -import org.springframework.stereotype.Component; - -@Component -public class FieldMapper { - public Field mapCreatingFieldDtoToField(CreatingFieldDto fieldDto) { - return Field.builder() - .address(fieldDto.getAddress()) - .latitude(fieldDto.getLatitude()) - .longitude(fieldDto.getLongitude()) - .area(fieldDto.getArea()) - .build(); - } -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldRepository.java b/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldRepository.java index 74f482f..0e462f0 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldRepository.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldRepository.java @@ -1,6 +1,6 @@ package dev.archie.rancherservice.field; -import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.mongodb.repository.MongoRepository; -public interface FieldRepository extends JpaRepository { +public interface FieldRepository extends MongoRepository { } diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldService.java b/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldService.java index d760613..fb52a10 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldService.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/field/FieldService.java @@ -1,10 +1,12 @@ package dev.archie.rancherservice.field; import dev.archie.rancherservice.field.dto.CreatingFieldDto; -import dev.archie.rancherservice.field.exceptions.FieldDoesNotExistsException; -import dev.archie.rancherservice.gardener.Gardener; -import dev.archie.rancherservice.gardener.GardenerRepository; -import dev.archie.rancherservice.gardener.exceptions.GardenerDoesNotExistsException; +import dev.archie.rancherservice.field.exception.NoSuchFieldWithIdException; +import dev.archie.rancherservice.landscape.FieldClient; +import dev.archie.rancherservice.landscape.dto.FieldDto; +import dev.archie.rancherservice.rancher.Gardener; +import dev.archie.rancherservice.rancher.GardenerRepository; +import dev.archie.rancherservice.rancher.GardenerService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -13,36 +15,63 @@ public class FieldService { private final FieldRepository fieldRepository; - private final FieldMapper fieldMapper; + + private final GardenerService gardenerService; private final GardenerRepository gardenerRepository; + private final FieldClient fieldClient; - public Field create(CreatingFieldDto fieldDto, Long gardenerId) { - Field field = fieldMapper.mapCreatingFieldDtoToField(fieldDto); - Gardener gardener = getGardener(gardenerId); + public Field create(CreatingFieldDto creatingFieldDto, String gardenerId) { + Gardener gardener = gardenerService.getById(gardenerId); + FieldDto fieldDto = fieldClient.create(creatingFieldDto, gardener.getInnerId()); + Field field = mapCreatingFieldDtoToField(creatingFieldDto); + field.setInnerId(fieldDto.getId()); field.setGardener(gardener); - return fieldRepository.save(field); + field = fieldRepository.save(field); + gardener.getFields().add(field); + gardenerRepository.save(gardener); + return field; } - public Field getById(Long id) { + public Field getById(String id) { return fieldRepository.findById(id) - .orElseThrow(() -> new FieldDoesNotExistsException(id)); + .orElseThrow(() -> new NoSuchFieldWithIdException(id)); } - public Field update(CreatingFieldDto fieldDto, Long id) { + public Field update(CreatingFieldDto creatingFieldDto, String id) { Field field = getById(id); - Field updatedField = fieldMapper.mapCreatingFieldDtoToField(fieldDto); - updatedField.setId(field.getId()); - updatedField.setGardener(field.getGardener()); - return fieldRepository.save(updatedField); + fieldClient.update(creatingFieldDto, field.getInnerId()); + Field updatedField = mapCreatingFieldDtoToField(creatingFieldDto); + copyField(field, updatedField); + field = fieldRepository.save(field); + Gardener gardener = field.getGardener(); + gardener.getFields().add(field); + gardenerRepository.save(gardener); + return field; } - public void delete(Long id) { + public void delete(String id) { Field field = getById(id); + fieldClient.delete(field.getInnerId()); fieldRepository.delete(field); } - private Gardener getGardener(Long gardenerId) { - return gardenerRepository.findById(gardenerId) - .orElseThrow(() -> new GardenerDoesNotExistsException(gardenerId)); + private static Field mapCreatingFieldDtoToField(CreatingFieldDto creatingFieldDto) { + return Field.builder() + .address(creatingFieldDto.getAddress()) + .area(creatingFieldDto.getFieldArea()) + .longitude(creatingFieldDto.getLongitude()) + .latitude(creatingFieldDto.getLatitude()) + .address(creatingFieldDto.getAddress()) + .jobs(creatingFieldDto.getJobs()) + .build(); + } + + private static void copyField(Field destination, Field source) { + destination.setJobs(source.getJobs()); + destination.setArea(source.getArea()); + destination.setAddress(source.getAddress()); + destination.setLatitude(source.getLatitude()); + destination.setLongitude(source.getLongitude()); } + } diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/field/dto/CreatingFieldDto.java b/rancher-service/src/main/java/dev/archie/rancherservice/field/dto/CreatingFieldDto.java index 3657590..aad90f4 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/field/dto/CreatingFieldDto.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/field/dto/CreatingFieldDto.java @@ -7,20 +7,17 @@ import org.n52.jackson.datatype.jts.GeometryDeserializer; import org.n52.jackson.datatype.jts.GeometrySerializer; +import java.util.List; + @Data public class CreatingFieldDto { - - private Long gardenerId; - - private String address; - private Double latitude; - private Double longitude; + private Double fieldArea; + private List jobs; + private String address; @JsonSerialize(using = GeometrySerializer.class) @JsonDeserialize(contentUsing = GeometryDeserializer.class) private Geometry area; -} - - +} \ No newline at end of file diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/field/exception/NoSuchFieldWithIdException.java b/rancher-service/src/main/java/dev/archie/rancherservice/field/exception/NoSuchFieldWithIdException.java new file mode 100644 index 0000000..4ff6b22 --- /dev/null +++ b/rancher-service/src/main/java/dev/archie/rancherservice/field/exception/NoSuchFieldWithIdException.java @@ -0,0 +1,10 @@ +package dev.archie.rancherservice.field.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; + +public class NoSuchFieldWithIdException extends ResponseStatusException { + public NoSuchFieldWithIdException(String id) { + super(HttpStatus.NOT_FOUND, "No such field with id: " + id); + } +} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/field/exceptions/FieldDoesNotExistsException.java b/rancher-service/src/main/java/dev/archie/rancherservice/field/exceptions/FieldDoesNotExistsException.java deleted file mode 100644 index 8df3b71..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/field/exceptions/FieldDoesNotExistsException.java +++ /dev/null @@ -1,10 +0,0 @@ -package dev.archie.rancherservice.field.exceptions; - -import org.springframework.http.HttpStatus; -import org.springframework.web.server.ResponseStatusException; - -public class FieldDoesNotExistsException extends ResponseStatusException { - public FieldDoesNotExistsException(Long id) { - super(HttpStatus.NOT_FOUND, "No such gardener with id: " + id); - } -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/GardenerController.java b/rancher-service/src/main/java/dev/archie/rancherservice/gardener/GardenerController.java deleted file mode 100644 index bb38549..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/GardenerController.java +++ /dev/null @@ -1,49 +0,0 @@ -package dev.archie.rancherservice.gardener; - -import dev.archie.rancherservice.gardener.dto.CreatingGardenerDto; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -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; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("gardeners") -@RequiredArgsConstructor -public class GardenerController { - - private final GardenerService gardenerService; - - @PostMapping - public Gardener create(@RequestBody CreatingGardenerDto gardenerDto) { - return gardenerService.create(gardenerDto); - } - - @GetMapping("/{id}") - public Gardener getById(@PathVariable Long id) { - return gardenerService.getById(id); - } - - @PutMapping("/{id}") - public Gardener update(@PathVariable Long id, @RequestBody CreatingGardenerDto gardenerDto) { - return gardenerService.update(id, gardenerDto); - } - - @DeleteMapping("/{id}") - public void delete(@PathVariable Long id) { - gardenerService.deleteById(id); - } - - @GetMapping - public Page getAll(@RequestParam(name = "size") int pageSize, - @RequestParam(name = "number") int pageNumber) { - return gardenerService.getAll(pageSize, pageNumber); - } - -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/GardenerRepository.java b/rancher-service/src/main/java/dev/archie/rancherservice/gardener/GardenerRepository.java deleted file mode 100644 index 770dd25..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/GardenerRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.archie.rancherservice.gardener; - -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; - -public interface GardenerRepository extends JpaRepository { - Optional findByEmail(String email); - - boolean existsByEmail(String email); -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/GardenerService.java b/rancher-service/src/main/java/dev/archie/rancherservice/gardener/GardenerService.java deleted file mode 100644 index 5bca016..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/GardenerService.java +++ /dev/null @@ -1,74 +0,0 @@ -package dev.archie.rancherservice.gardener; - -import dev.archie.rancherservice.field.Field; -import dev.archie.rancherservice.field.FieldService; -import dev.archie.rancherservice.gardener.dto.CreatingGardenerDto; -import dev.archie.rancherservice.gardener.exceptions.GardenerAlreadyExistsException; -import dev.archie.rancherservice.gardener.exceptions.GardenerDoesNotExistsException; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Optional; - -@Service -@RequiredArgsConstructor -public class GardenerService { - - private final GardenerRepository gardenerRepository; - private final FieldService fieldService; - - public Gardener create(CreatingGardenerDto gardenerDto) { - Gardener gardener = mapCreatingGardenerDtoToGardener(gardenerDto); - if (gardenerRepository.existsByEmail(gardener.getEmail())) { - throw new GardenerAlreadyExistsException(gardener.getEmail()); - } - gardenerRepository.save(gardener); - List fields = gardenerDto.getFields().stream() - .map(fieldDto -> fieldService.create(fieldDto, gardener.getId())) - .toList(); - gardener.setFields(fields); - return gardener; - } - - public Gardener getById(Long id) { - return gardenerRepository.findById(id) - .orElseThrow(() -> new GardenerDoesNotExistsException(id)); - } - - public Gardener update(Long id, CreatingGardenerDto gardenerDto) { - Gardener existingGardener = getById(id); - Optional possibleGardenerByNewEmail = gardenerRepository.findByEmail(gardenerDto.getEmail()); - if (possibleGardenerByNewEmail.isPresent() && !possibleGardenerByNewEmail.get().equals(existingGardener)) { - throw new GardenerAlreadyExistsException(gardenerDto.getEmail()); - } - existingGardener.setEmail(gardenerDto.getEmail()); - existingGardener.setPhone(gardenerDto.getPhone()); - existingGardener.setLastName(gardenerDto.getLastName()); - existingGardener.setFirstName(gardenerDto.getFirstName()); - return gardenerRepository.save(existingGardener); - } - - public void deleteById(Long id) { - Gardener gardener = getById(id); - gardenerRepository.delete(gardener); - } - - private Gardener mapCreatingGardenerDtoToGardener(CreatingGardenerDto gardenerDto) { - return Gardener.builder() - .phone(gardenerDto.getPhone()) - .lastName(gardenerDto.getLastName()) - .firstName(gardenerDto.getFirstName()) - .email(gardenerDto.getEmail()) - .phone(gardenerDto.getPhone()) - .build(); - } - - public Page getAll(int pageSize, int pageNumber) { - PageRequest request = PageRequest.of(pageNumber, pageSize, Sort.by("email")); - return gardenerRepository.findAll(request); - } -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/dto/CreatingGardenerDto.java b/rancher-service/src/main/java/dev/archie/rancherservice/gardener/dto/CreatingGardenerDto.java deleted file mode 100644 index 4b3d921..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/dto/CreatingGardenerDto.java +++ /dev/null @@ -1,27 +0,0 @@ -package dev.archie.rancherservice.gardener.dto; - -import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.annotation.Nulls; -import dev.archie.rancherservice.field.dto.CreatingFieldDto; -import lombok.Data; - -import java.util.List; - -@Data -public class CreatingGardenerDto { - - private String firstName; - - private String lastName; - - private String email; - - private String phone; - - private List fields; - - @JsonSetter(nulls = Nulls.AS_EMPTY) - public void setFields(List fields) { - this.fields = fields; - } -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/exceptions/GardenerAlreadyExistsException.java b/rancher-service/src/main/java/dev/archie/rancherservice/gardener/exceptions/GardenerAlreadyExistsException.java deleted file mode 100644 index 82b0bdb..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/exceptions/GardenerAlreadyExistsException.java +++ /dev/null @@ -1,11 +0,0 @@ -package dev.archie.rancherservice.gardener.exceptions; - -import org.springframework.http.HttpStatus; -import org.springframework.web.server.ResponseStatusException; - -public class GardenerAlreadyExistsException extends ResponseStatusException { - - public GardenerAlreadyExistsException(String email) { - super(HttpStatus.BAD_REQUEST, "Gardener with such email already exists: " + email); - } -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/exceptions/GardenerDoesNotExistsException.java b/rancher-service/src/main/java/dev/archie/rancherservice/gardener/exceptions/GardenerDoesNotExistsException.java deleted file mode 100644 index af83022..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/exceptions/GardenerDoesNotExistsException.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.archie.rancherservice.gardener.exceptions; - -import org.springframework.http.HttpStatus; -import org.springframework.web.server.ResponseStatusException; - -public class GardenerDoesNotExistsException extends ResponseStatusException { - - public GardenerDoesNotExistsException(Long id) { - super(HttpStatus.NOT_FOUND, "Gardener with such id not found: " + id); - } - -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/landscape/FieldClient.java b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/FieldClient.java new file mode 100644 index 0000000..e2d9aea --- /dev/null +++ b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/FieldClient.java @@ -0,0 +1,30 @@ +package dev.archie.rancherservice.landscape; + +import dev.archie.rancherservice.field.dto.CreatingFieldDto; +import dev.archie.rancherservice.landscape.dto.FieldDto; +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; + +import java.util.UUID; + +@FeignClient(path = "/fields", url = "${application.landscape.rest.url}", name = "field-client") +public interface FieldClient { + + @PostMapping("/{gardenerId}") + FieldDto create(@RequestBody CreatingFieldDto creatingFieldDto, @PathVariable UUID gardenerId); + + @GetMapping("/{id}") + FieldDto getById(@PathVariable Long id); + + @PutMapping("/{id}") + FieldDto update(@RequestBody CreatingFieldDto creatingFieldDto, @PathVariable Long id); + + @DeleteMapping("/{id}") + void delete(@PathVariable Long id); + +} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/landscape/GardenerClient.java b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/GardenerClient.java new file mode 100644 index 0000000..f8e83e7 --- /dev/null +++ b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/GardenerClient.java @@ -0,0 +1,31 @@ +package dev.archie.rancherservice.landscape; + +import dev.archie.rancherservice.landscape.dto.GardenerDto; +import dev.archie.rancherservice.rancher.dto.CreatingGardenerDto; +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; + +import java.util.UUID; + +@FeignClient(name = "gardener-client", url = "${application.landscape.rest.url}", path = "gardeners") +public interface GardenerClient { + + @PostMapping + GardenerDto create(@RequestBody CreatingGardenerDto creatingGardenerDto); + + @GetMapping("/{id}") + GardenerDto getById(@PathVariable UUID id); + + @PutMapping("/{id}") + GardenerDto update(@PathVariable UUID id, + @RequestBody CreatingGardenerDto creatingGardenerDto); + + @DeleteMapping("/{id}") + void delete(@PathVariable UUID id); + +} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/landscape/LandscapeClient.java b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/LandscapeClient.java index 72af888..6622ad7 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/landscape/LandscapeClient.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/LandscapeClient.java @@ -1,5 +1,6 @@ package dev.archie.rancherservice.landscape; +import dev.archie.rancherservice.landscape.dto.CreatingUserDto; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/landscape/LandscapeService.java b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/LandscapeService.java index 277e5a7..c4308c1 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/landscape/LandscapeService.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/LandscapeService.java @@ -1,5 +1,6 @@ package dev.archie.rancherservice.landscape; +import dev.archie.rancherservice.landscape.dto.CreatingUserDto; import dev.archie.rancherservice.rancher.exception.UnableToConnectToInnerService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/CreatingUserDto.java b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/dto/CreatingUserDto.java similarity index 84% rename from handyman-service/src/main/java/dev/archie/handymanservice/landscape/CreatingUserDto.java rename to rancher-service/src/main/java/dev/archie/rancherservice/landscape/dto/CreatingUserDto.java index fd60383..9523c54 100644 --- a/handyman-service/src/main/java/dev/archie/handymanservice/landscape/CreatingUserDto.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/dto/CreatingUserDto.java @@ -1,4 +1,4 @@ -package dev.archie.handymanservice.landscape; +package dev.archie.rancherservice.landscape.dto; import lombok.Builder; import lombok.Data; diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/landscape/dto/FieldDto.java b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/dto/FieldDto.java new file mode 100644 index 0000000..ea39ae1 --- /dev/null +++ b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/dto/FieldDto.java @@ -0,0 +1,19 @@ +package dev.archie.rancherservice.landscape.dto; + +import lombok.Data; +import org.locationtech.jts.geom.Geometry; + +@Data +public class FieldDto { + + private Long id; + + private String address; + + private Double latitude; + + private Double longitude; + + private Geometry area; + +} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/landscape/dto/GardenerDto.java b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/dto/GardenerDto.java new file mode 100644 index 0000000..b802552 --- /dev/null +++ b/rancher-service/src/main/java/dev/archie/rancherservice/landscape/dto/GardenerDto.java @@ -0,0 +1,36 @@ +package dev.archie.rancherservice.landscape.dto; + +import dev.archie.rancherservice.landscape.UserType; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +@Data +public class GardenerDto { + + private UUID id; + + private String login; + + private String email; + + private String phoneNumber; + + private LocalDateTime createdAt; + + private LocalDateTime lastUpdatedAt; + + private Double latitude; + + private Double longitude; + + private UserType userType; + + private String firstName; + + private String lastName; + + private List fields; +} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/Gardener.java b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/Gardener.java similarity index 54% rename from rancher-service/src/main/java/dev/archie/rancherservice/gardener/Gardener.java rename to rancher-service/src/main/java/dev/archie/rancherservice/rancher/Gardener.java index 3fecbcf..e42ed10 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/gardener/Gardener.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/Gardener.java @@ -1,4 +1,4 @@ -package dev.archie.rancherservice.gardener; +package dev.archie.rancherservice.rancher; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSetter; @@ -9,44 +9,38 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.DocumentReference; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; import java.util.List; +import java.util.UUID; @Builder @Getter @Setter @NoArgsConstructor @AllArgsConstructor -@Entity -@Table(name = "gardener") +@Document(collection = "gardeners") public class Gardener { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + private String id; + + private UUID innerId; - @Column(name = "first_name", nullable = false) private String firstName; - @Column(name = "last_name", nullable = false) private String lastName; - @Column(name = "email", nullable = false) private String email; - @Column(name = "phone") private String phone; + private String login; + @JsonIgnoreProperties(value = "gardener") - @OneToMany(mappedBy = "gardener", cascade = CascadeType.REMOVE, orphanRemoval = true) + @DocumentReference private List fields; @JsonSetter(nulls = Nulls.AS_EMPTY) diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/RancherController.java b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/GardenerController.java similarity index 58% rename from rancher-service/src/main/java/dev/archie/rancherservice/rancher/RancherController.java rename to rancher-service/src/main/java/dev/archie/rancherservice/rancher/GardenerController.java index e14be07..1a26dd1 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/RancherController.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/GardenerController.java @@ -1,6 +1,6 @@ package dev.archie.rancherservice.rancher; -import dev.archie.rancherservice.rancher.dto.CreatingProfileDto; +import dev.archie.rancherservice.rancher.dto.CreatingGardenerDto; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -13,18 +13,18 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/ranchers") -public class RancherController { +@RequestMapping("/gardeners") +public class GardenerController { - private final RancherService rancherService; + private final GardenerService gardenerService; /** - * @param creatingProfileDto rancher to create + * @param creatingGardenerDto rancher to create * @return created rancher's profile */ @PostMapping - public Profile create(@RequestBody CreatingProfileDto creatingProfileDto) { - return rancherService.create(creatingProfileDto); + public Gardener create(@RequestBody CreatingGardenerDto creatingGardenerDto) { + return gardenerService.create(creatingGardenerDto); } /** @@ -32,18 +32,18 @@ public Profile create(@RequestBody CreatingProfileDto creatingProfileDto) { * @return found profile */ @GetMapping("/{id}") - public Profile getById(@PathVariable String id) { - return rancherService.getProfileById(id); + public Gardener getById(@PathVariable String id) { + return gardenerService.getById(id); } /** * @param id of existing rancher - * @param creatingProfileDto new fields. New email should not exist + * @param creatingGardenerDto new fields. New email should not exist * @return updated profile */ @PutMapping("/{id}") - public Profile update(@PathVariable String id, @RequestBody CreatingProfileDto creatingProfileDto) { - return rancherService.update(id, creatingProfileDto); + public Gardener update(@PathVariable String id, @RequestBody CreatingGardenerDto creatingGardenerDto) { + return gardenerService.update(id, creatingGardenerDto); } /** @@ -51,7 +51,7 @@ public Profile update(@PathVariable String id, @RequestBody CreatingProfileDto c */ @DeleteMapping("/{id}") public void delete(@PathVariable String id) { - rancherService.delete(id); + gardenerService.delete(id); } } diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/RancherRepository.java b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/GardenerRepository.java similarity index 51% rename from rancher-service/src/main/java/dev/archie/rancherservice/rancher/RancherRepository.java rename to rancher-service/src/main/java/dev/archie/rancherservice/rancher/GardenerRepository.java index d5d1ca7..a0ce71d 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/RancherRepository.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/GardenerRepository.java @@ -2,5 +2,7 @@ import org.springframework.data.mongodb.repository.MongoRepository; -public interface RancherRepository extends MongoRepository { +import java.util.Optional; + +public interface GardenerRepository extends MongoRepository { } diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/GardenerService.java b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/GardenerService.java new file mode 100644 index 0000000..a78595b --- /dev/null +++ b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/GardenerService.java @@ -0,0 +1,70 @@ +package dev.archie.rancherservice.rancher; + +import dev.archie.rancherservice.landscape.GardenerClient; +import dev.archie.rancherservice.landscape.dto.GardenerDto; +import dev.archie.rancherservice.rancher.dto.CreatingGardenerDto; +import dev.archie.rancherservice.rancher.exception.NoSuchUserException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class GardenerService { + + private final GardenerRepository gardenerRepository; + private final GardenerClient gardenerClient; + + /** + * @param creatingGardenerDto rancher to create + * @return created rancher's profile + */ + public Gardener create(CreatingGardenerDto creatingGardenerDto) { + GardenerDto gardenerDto = gardenerClient.create(creatingGardenerDto); + Gardener gardener = mapGardenerDtoToGardener(creatingGardenerDto, gardenerDto); + gardener.setInnerId(gardenerDto.getId()); + return gardenerRepository.save(gardener); + } + + /** + * @param id of existing rancher + * @return found profile + */ + public Gardener getById(String id) { + return gardenerRepository.findById(id) + .orElseThrow(() -> new NoSuchUserException(id)); + } + + /** + * @param id of existing rancher + * @param creatingGardenerDto new fields. New email should not exist + * @return updated profile + */ + public Gardener update(String id, CreatingGardenerDto creatingGardenerDto) { + Gardener gardener = getById(id); + GardenerDto user = gardenerClient.update(gardener.getInnerId(), creatingGardenerDto); + gardener = mapGardenerDtoToGardener(creatingGardenerDto, user); + gardener.setId(gardener.getId()); + return gardenerRepository.save(gardener); + } + + /** + * @param id of existing user + */ + public void delete(String id) { + Gardener gardener= getById(id); + gardenerClient.delete(gardener.getInnerId()); + gardenerRepository.delete(gardener); + } + + private static Gardener mapGardenerDtoToGardener(CreatingGardenerDto creatingGardenerDto, GardenerDto user) { + return Gardener.builder() + .lastName(creatingGardenerDto.getLastName()) + .firstName(creatingGardenerDto.getFirstName()) + .phone(user.getPhoneNumber()) + .email(user.getEmail()) + .login(user.getLogin()) + .innerId(user.getId()) + .build(); + } + +} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/Plot.java b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/Plot.java deleted file mode 100644 index 8b98d68..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/Plot.java +++ /dev/null @@ -1,29 +0,0 @@ -package dev.archie.rancherservice.rancher; - -import lombok.Builder; -import lombok.Data; -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.Document; - -import java.util.List; -import java.util.UUID; - -@Data -@Builder -@Document -public class Plot { - - @Id - private String id; - - private UUID innerId; - - private Double latitude; - - private Double longitude; - - private Double area; - - private List jobs; - -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/Profile.java b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/Profile.java deleted file mode 100644 index 3fc16ab..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/Profile.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.archie.rancherservice.rancher; - -import dev.archie.rancherservice.landscape.User; -import lombok.Builder; -import lombok.Data; - -@Data -@Builder -public class Profile { - - private Plot plot; - - private User rancher; -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/RancherService.java b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/RancherService.java deleted file mode 100644 index 7fd0f2e..0000000 --- a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/RancherService.java +++ /dev/null @@ -1,97 +0,0 @@ -package dev.archie.rancherservice.rancher; - -import dev.archie.rancherservice.landscape.CreatingUserDto; -import dev.archie.rancherservice.landscape.LandscapeService; -import dev.archie.rancherservice.landscape.User; -import dev.archie.rancherservice.rancher.dto.CreatingProfileDto; -import dev.archie.rancherservice.rancher.exception.NoSuchUserException; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class RancherService { - - private static final long RANCHER_USER_TYPE = 1; - - private final LandscapeService landscapeService; - - private final RancherRepository rancherRepository; - - /** - * @param creatingProfileDto rancher to create - * @return created rancher's profile - */ - public Profile create(CreatingProfileDto creatingProfileDto) { - CreatingUserDto creatingUserDto = mapCreatingProfileDtoToUserOne(creatingProfileDto); - User user = landscapeService.createUser(creatingUserDto); - Plot plot = mapProfileToPlot(creatingProfileDto, user); - rancherRepository.insert(plot); - return new Profile(plot, user); - } - - /** - * @param id of existing rancher - * @return found profile - */ - public Profile getProfileById(String id) { - Plot plot = rancherRepository.findById(id) - .orElseThrow(() -> new NoSuchUserException(id)); - User rancher = landscapeService.getById(plot.getInnerId()); - return new Profile(plot, rancher); - } - - /** - * @param id of rancher's plot - * @return found plot - */ - public Plot getPlotById(String id) { - return rancherRepository.findById(id) - .orElseThrow(() -> new NoSuchUserException(id)); - } - - /** - * @param id of existing rancher - * @param creatingProfileDto new fields. New email should not exist - * @return updated profile - */ - public Profile update(String id, CreatingProfileDto creatingProfileDto) { - Plot plot = getPlotById(id); - CreatingUserDto creatingUserDto = mapCreatingProfileDtoToUserOne(creatingProfileDto); - User user = landscapeService.update(plot.getInnerId(), creatingUserDto); - Plot updatedPlot = mapProfileToPlot(creatingProfileDto, user); - updatedPlot.setId(plot.getId()); - rancherRepository.save(updatedPlot); - return new Profile(updatedPlot, user); - } - - /** - * @param id of existing user - */ - public void delete(String id) { - Plot plot = getPlotById(id); - landscapeService.delete(plot.getInnerId()); - rancherRepository.delete(plot); - } - - private static CreatingUserDto mapCreatingProfileDtoToUserOne(CreatingProfileDto creatingProfileDto) { - return CreatingUserDto.builder() - .userTypeId(RANCHER_USER_TYPE) - .phoneNumber(creatingProfileDto.getPhoneNumber()) - .login(creatingProfileDto.getLogin()) - .longitude(creatingProfileDto.getLongitude()) - .latitude(creatingProfileDto.getLatitude()) - .email(creatingProfileDto.getEmail()) - .build(); - } - - private static Plot mapProfileToPlot(CreatingProfileDto creatingProfileDto, User user) { - return Plot.builder() - .jobs(creatingProfileDto.getJobs()) - .innerId(user.getId()) - .longitude(user.getLongitude()) - .latitude(user.getLatitude()) - .area(creatingProfileDto.getArea()) - .build(); - } -} diff --git a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/dto/CreatingProfileDto.java b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/dto/CreatingGardenerDto.java similarity index 62% rename from rancher-service/src/main/java/dev/archie/rancherservice/rancher/dto/CreatingProfileDto.java rename to rancher-service/src/main/java/dev/archie/rancherservice/rancher/dto/CreatingGardenerDto.java index a0cb06f..9ebbedf 100644 --- a/rancher-service/src/main/java/dev/archie/rancherservice/rancher/dto/CreatingProfileDto.java +++ b/rancher-service/src/main/java/dev/archie/rancherservice/rancher/dto/CreatingGardenerDto.java @@ -3,24 +3,22 @@ import lombok.Builder; import lombok.Data; -import java.util.List; - @Data @Builder(toBuilder = true) -public class CreatingProfileDto { +public class CreatingGardenerDto { private String login; private String email; - private String phoneNumber; + private String phone; - private Double latitude; + private String firstName; - private Double longitude; + private String lastName; - private Double area; + private Double latitude; - private List jobs; + private Double longitude; } diff --git a/rancher-service/src/test/java/dev/archie/rancherservice/integration/rancher/RancherConstants.java b/rancher-service/src/test/java/dev/archie/rancherservice/integration/rancher/RancherConstants.java index ad4471e..30b6c43 100644 --- a/rancher-service/src/test/java/dev/archie/rancherservice/integration/rancher/RancherConstants.java +++ b/rancher-service/src/test/java/dev/archie/rancherservice/integration/rancher/RancherConstants.java @@ -1,16 +1,16 @@ package dev.archie.rancherservice.integration.rancher; import dev.archie.rancherservice.landscape.User; -import dev.archie.rancherservice.rancher.dto.CreatingProfileDto; +import dev.archie.rancherservice.rancher.dto.CreatingGardenerDto; import java.util.List; public class RancherConstants { - public static final CreatingProfileDto CREATING_PROFILE_DTO = CreatingProfileDto.builder() + public static final CreatingGardenerDto CREATING_PROFILE_DTO = CreatingGardenerDto.builder() .login("archik") .email("arhcik@ya.ru") - .phoneNumber("+123321123") + .phone("+123321123") .latitude(2.0) .longitude(3.0) .area(12.0) diff --git a/rancher-service/src/test/java/dev/archie/rancherservice/integration/rancher/RancherControllerTest.java b/rancher-service/src/test/java/dev/archie/rancherservice/integration/rancher/RancherControllerTest.java deleted file mode 100644 index 96a412c..0000000 --- a/rancher-service/src/test/java/dev/archie/rancherservice/integration/rancher/RancherControllerTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package dev.archie.rancherservice.integration.rancher; - -import dev.archie.rancherservice.integration.common.AbstractIntegrationTest; -import dev.archie.rancherservice.landscape.LandscapeService; -import dev.archie.rancherservice.landscape.User; -import dev.archie.rancherservice.rancher.Plot; -import dev.archie.rancherservice.rancher.Profile; -import dev.archie.rancherservice.rancher.dto.CreatingProfileDto; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.mockito.Mockito; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; - -import java.nio.charset.StandardCharsets; - -@TestMethodOrder(value = MethodOrderer.OrderAnnotation.class) -@AutoConfigureMockMvc -public class RancherControllerTest extends AbstractIntegrationTest { - - - @MockBean - private LandscapeService landscapeService; - - @Autowired - private MockMvc mockMvc; - - @BeforeEach - void setUp() { - Mockito.when(landscapeService.createUser(Mockito.any())).thenReturn(RancherConstants.MOCK_RESPONSE_USER); - Mockito.when(landscapeService.getById(Mockito.any())).thenReturn(RancherConstants.MOCK_RESPONSE_USER); - Mockito.when(landscapeService.update(Mockito.any(), Mockito.any())).thenReturn(RancherConstants.MOCK_RESPONSE_USER); - } - - @Test - @Order(1) - void postRanchersShouldCreateNewUser() throws Exception { - String creatingProfileDtoSerialized = objectMapper.writeValueAsString(RancherConstants.CREATING_PROFILE_DTO); - String responseSerialized = mockMvc.perform(MockMvcRequestBuilders.post("/ranchers") - .contentType(MediaType.APPLICATION_JSON) - .content(creatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Profile actualProfile = objectMapper.readValue(responseSerialized, Profile.class); - User rancher = actualProfile.getRancher(); - Plot plot = actualProfile.getPlot(); - Assertions.assertEquals(RancherConstants.MOCK_RESPONSE_USER.getLogin(), rancher.getLogin()); - Assertions.assertEquals(RancherConstants.MOCK_RESPONSE_USER.getEmail(), rancher.getEmail()); - Assertions.assertEquals(RancherConstants.MOCK_RESPONSE_USER.getPhoneNumber(), rancher.getPhoneNumber()); - Assertions.assertEquals(RancherConstants.MOCK_RESPONSE_USER.getLatitude(), rancher.getLatitude()); - Assertions.assertEquals(RancherConstants.MOCK_RESPONSE_USER.getLongitude(), rancher.getLongitude()); - Assertions.assertEquals(RancherConstants.CREATING_PROFILE_DTO.getArea(), plot.getArea()); - Assertions.assertEquals(RancherConstants.CREATING_PROFILE_DTO.getJobs(), plot.getJobs()); - } - - @Test - @Order(2) - void deleteRanchersShouldDeleteExistingRancher() throws Exception { - String creatingProfileDtoSerialized = objectMapper.writeValueAsString(RancherConstants.CREATING_PROFILE_DTO); - String responseSerialized = mockMvc.perform(MockMvcRequestBuilders.post("/ranchers") - .contentType(MediaType.APPLICATION_JSON) - .content(creatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Profile actualProfile = objectMapper.readValue(responseSerialized, Profile.class); - Plot plot = actualProfile.getPlot(); - - mockMvc.perform(MockMvcRequestBuilders.delete("/ranchers/" + plot.getId()) - .contentType(MediaType.APPLICATION_JSON) - .content(creatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Mockito.verify(landscapeService, Mockito.times(1)).delete(Mockito.any()); - } - - @Test - @Order(3) - void getRanchersShouldReturnExistingUser() throws Exception { - String creatingProfileDtoSerialized = objectMapper.writeValueAsString(RancherConstants.CREATING_PROFILE_DTO); - String responseSerialized = mockMvc.perform(MockMvcRequestBuilders.post("/ranchers") - .contentType(MediaType.APPLICATION_JSON) - .content(creatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Profile createdProfile = objectMapper.readValue(responseSerialized, Profile.class); - Plot createdPlot = createdProfile.getPlot(); - - String responseUserSerialized = mockMvc.perform(MockMvcRequestBuilders.get("/ranchers/" + createdPlot.getId())) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - - Profile actualProfile = objectMapper.readValue(responseUserSerialized, Profile.class); - Plot actualPlot = actualProfile.getPlot(); - Assertions.assertEquals(createdPlot, actualPlot); - } - - @Test - @Order(4) - void putRanchersShouldUpdateExistingUser() throws Exception { - String creatingProfileDtoSerialized = objectMapper.writeValueAsString(RancherConstants.CREATING_PROFILE_DTO); - String responseSerialized = mockMvc.perform(MockMvcRequestBuilders.post("/ranchers") - .contentType(MediaType.APPLICATION_JSON) - .content(creatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Profile createdProfile = objectMapper.readValue(responseSerialized, Profile.class); - Plot createdPlot = createdProfile.getPlot(); - - CreatingProfileDto updatingProfileDto = RancherConstants.CREATING_PROFILE_DTO.toBuilder().build(); - updatingProfileDto.setArea(123.0); - String updatingProfileDtoSerialized = objectMapper.writeValueAsString(updatingProfileDto); - - String updatedProfileSerialized = mockMvc.perform(MockMvcRequestBuilders.put("/ranchers/" + createdPlot.getId()) - .contentType(MediaType.APPLICATION_JSON) - .content(updatingProfileDtoSerialized)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andReturn() - .getResponse() - .getContentAsString(StandardCharsets.UTF_8); - Profile updatedProfile = objectMapper.readValue(updatedProfileSerialized, Profile.class); - Plot updatedPlot = updatedProfile.getPlot(); - - Assertions.assertEquals(updatingProfileDto.getArea(), updatedPlot.getArea()); - Assertions.assertEquals(createdPlot.getLongitude(), updatedPlot.getLongitude()); - Assertions.assertEquals(createdPlot.getLatitude(), updatedPlot.getLatitude()); - Assertions.assertEquals(createdPlot.getJobs(), updatedPlot.getJobs()); - Assertions.assertEquals(createdPlot.getId(), updatedPlot.getId()); - Assertions.assertEquals(createdPlot.getInnerId(), updatedPlot.getInnerId()); - } - -}