From 9ac0fc82e4a771b9e39d41eaf97dbdf9f82fd6ab Mon Sep 17 00:00:00 2001 From: Iris Flystam Date: Thu, 19 Sep 2024 15:47:46 +0200 Subject: [PATCH 1/3] First try for the java stuff, without a .yml file --- .gitignore | 3 + src/main/java/com/booleanuk/api/Main.java | 11 + .../api/controller/PostController.java | 221 ++++++++++++++++++ .../api/controller/UserController.java | 137 +++++++++++ .../com/booleanuk/api/model/ApiResponse.java | 16 ++ .../java/com/booleanuk/api/model/Friend.java | 42 ++++ .../java/com/booleanuk/api/model/Like.java | 42 ++++ .../java/com/booleanuk/api/model/Post.java | 58 +++++ .../java/com/booleanuk/api/model/User.java | 52 +++++ .../api/repository/FriendRepository.java | 7 + .../api/repository/LikeRepository.java | 7 + .../api/repository/PostRepository.java | 7 + .../api/repository/UserRepository.java | 7 + src/main/resources/application.yml | 7 - 14 files changed, 610 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/booleanuk/api/Main.java create mode 100644 src/main/java/com/booleanuk/api/controller/PostController.java create mode 100644 src/main/java/com/booleanuk/api/controller/UserController.java create mode 100644 src/main/java/com/booleanuk/api/model/ApiResponse.java create mode 100644 src/main/java/com/booleanuk/api/model/Friend.java create mode 100644 src/main/java/com/booleanuk/api/model/Like.java create mode 100644 src/main/java/com/booleanuk/api/model/Post.java create mode 100644 src/main/java/com/booleanuk/api/model/User.java create mode 100644 src/main/java/com/booleanuk/api/repository/FriendRepository.java create mode 100644 src/main/java/com/booleanuk/api/repository/LikeRepository.java create mode 100644 src/main/java/com/booleanuk/api/repository/PostRepository.java create mode 100644 src/main/java/com/booleanuk/api/repository/UserRepository.java delete mode 100644 src/main/resources/application.yml diff --git a/.gitignore b/.gitignore index c2065bc..7cf595e 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ out/ ### VS Code ### .vscode/ + +application.yml +*.jar diff --git a/src/main/java/com/booleanuk/api/Main.java b/src/main/java/com/booleanuk/api/Main.java new file mode 100644 index 0000000..8e749e0 --- /dev/null +++ b/src/main/java/com/booleanuk/api/Main.java @@ -0,0 +1,11 @@ +package com.booleanuk.api; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Main { + public static void main(String[] args) { + SpringApplication.run(Main.class, args); + } +} diff --git a/src/main/java/com/booleanuk/api/controller/PostController.java b/src/main/java/com/booleanuk/api/controller/PostController.java new file mode 100644 index 0000000..979d620 --- /dev/null +++ b/src/main/java/com/booleanuk/api/controller/PostController.java @@ -0,0 +1,221 @@ +package com.booleanuk.api.controller; + +import com.booleanuk.api.model.ApiResponse; +import com.booleanuk.api.model.Like; +import com.booleanuk.api.model.Post; +import com.booleanuk.api.model.User; +import com.booleanuk.api.repository.LikeRepository; +import com.booleanuk.api.repository.PostRepository; +import com.booleanuk.api.repository.UserRepository; +import io.micrometer.common.util.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Optional; + +@RestController +@RequestMapping("post") +public class PostController { + @Autowired + private final PostRepository postRepository; + + @Autowired + private final UserRepository userRepository; + + @Autowired + private final LikeRepository likeRepository; + + public PostController(PostRepository postRepository, UserRepository userRepository, LikeRepository likeRepository) { + this.postRepository = postRepository; + this.userRepository = userRepository; + this.likeRepository = likeRepository; + } + + @PostMapping("{userId}") + public ResponseEntity> createPost (@PathVariable int userId, @RequestBody Post postDetails) { + Optional use = this.userRepository.findById(userId); + + if(use.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find user with id " + userId); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + User user = use.get(); + + if(postDetails.isInvalid()) { + ApiResponse response = new ApiResponse<>("error", "Could not create a post with the specified parameters."); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + Post post = new Post(postDetails.getContents(), user, null); + user.getPosts().add(post); + + this.postRepository.save(post); + this.userRepository.save(user); + + ApiResponse response = new ApiResponse<>("success", post); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } + + @PostMapping("{userId}/{postId}") + public ResponseEntity> createPost (@PathVariable int userId, @PathVariable int postId, @RequestBody Post postDetails) { + Optional use = this.userRepository.findById(userId); + + if(use.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find user with id " + userId); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + User user = use.get(); + + Optional pos = this.postRepository.findById(postId); + if(pos.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find post with id " + userId); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + Post post = pos.get(); + + if(postDetails.isInvalid()) { + ApiResponse response = new ApiResponse<>("error", "Could not create a post with the specified parameters."); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + Post comment = new Post(postDetails.getContents(), user, post); + + user.getPosts().add(comment); + post.getComments().add(comment); + + this.postRepository.save(comment); + this.postRepository.save(post); + this.userRepository.save(user); + + ApiResponse response = new ApiResponse<>("success", comment); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } + + @PostMapping("{postId}/like/{userId}") + public ResponseEntity> createLike (@PathVariable int userId, @PathVariable int postId) { + Optional use = this.userRepository.findById(userId); + if(use.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find user with id " + userId); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + User user = use.get(); + + Optional pos = this.postRepository.findById(postId); + if(pos.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find post with id " + userId); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + Post post = pos.get(); + + Like like = new Like(user, post); + user.getLikes().add(like); + post.getLikes().add(like); + + this.likeRepository.save(like); + this.postRepository.save(post); + this.userRepository.save(user); + + ApiResponse response = new ApiResponse<>("success", like); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } + + @PostMapping("{postId}/repost/{userId}") + public ResponseEntity> repost (@PathVariable int userId, @PathVariable int postId) { + Optional use = this.userRepository.findById(userId); + if(use.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find user with id " + userId); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + User user = use.get(); + + Optional pos = this.postRepository.findById(postId); + if(pos.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find post with id " + userId); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + Post post = pos.get(); + + user.getPosts().add(post); + this.userRepository.save(user); + + ApiResponse response = new ApiResponse<>("success", post); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } + + @GetMapping + public ResponseEntity>> readAll() { + List posts = this.postRepository.findAll(); + ApiResponse> response = new ApiResponse<>("success", posts); + return new ResponseEntity<>(response, HttpStatus.OK); + } + + @GetMapping("{id}") + public ResponseEntity> readOne (@PathVariable int id) { + Optional pos = this.postRepository.findById(id); + + if(pos.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find post with id " + id); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + + Post post = pos.get(); + ApiResponse response = new ApiResponse<>("success", post); + return new ResponseEntity<>(response, HttpStatus.OK); + } + + @PutMapping("{id}") + public ResponseEntity> update (@PathVariable int id, @RequestBody String newContents) { + Optional pos = this.postRepository.findById(id); + + if(pos.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find post with id " + id); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + + Post post = pos.get(); + + if(StringUtils.isBlank(newContents)) { + ApiResponse response = new ApiResponse<>("error", "Could not create a post with the specified parameters."); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + post.setContents(newContents); + + ApiResponse response = new ApiResponse<>("success", post); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } + + @DeleteMapping("{id}") + public ResponseEntity> delete (@PathVariable int id) { + Optional pos = this.postRepository.findById(id); + + if(pos.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find post with id " + id); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + + Post post = pos.get(); + this.postRepository.delete(post); + + ApiResponse response = new ApiResponse<>("success", post); + return new ResponseEntity<>(response, HttpStatus.OK); + } + + @DeleteMapping("like/{id}") + public ResponseEntity> deleteLike (@PathVariable int id) { + Optional lik = this.likeRepository.findById(id); + + if(lik.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find like with id " + id); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + + Like like = lik.get(); + + ApiResponse response = new ApiResponse<>("success", like); + return new ResponseEntity<>(response, HttpStatus.OK); + } +} diff --git a/src/main/java/com/booleanuk/api/controller/UserController.java b/src/main/java/com/booleanuk/api/controller/UserController.java new file mode 100644 index 0000000..51787ae --- /dev/null +++ b/src/main/java/com/booleanuk/api/controller/UserController.java @@ -0,0 +1,137 @@ +package com.booleanuk.api.controller; + +import com.booleanuk.api.model.ApiResponse; +import com.booleanuk.api.model.Friend; +import com.booleanuk.api.model.Like; +import com.booleanuk.api.model.User; +import com.booleanuk.api.repository.FriendRepository; +import com.booleanuk.api.repository.LikeRepository; +import com.booleanuk.api.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Optional; + +@RestController +@RequestMapping("user") +public class UserController { + @Autowired + private final UserRepository repository; + + @Autowired + private final FriendRepository friendRepository; + + public UserController(UserRepository userRepository, FriendRepository friendRepository) { + this.repository = userRepository; + this.friendRepository = friendRepository; + } + + @PostMapping + public ResponseEntity> create (@RequestBody User userDetails) { + if(userDetails.isInvalid()) { + ApiResponse response = new ApiResponse<>("error", "Could not create a user with the specified parameters."); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + User user = new User(userDetails.getName(), userDetails.getAboutMe()); + ApiResponse response = new ApiResponse<>("success", repository.save(user)); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } + + @PostMapping("{userId}/friendRequest/{targetId}") + public ResponseEntity> createFriendRequest (@PathVariable int userId, @PathVariable int targetId) { + Optional use = this.repository.findById(userId); + if(use.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find user with id " + userId); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + User user = use.get(); + + Optional tar = this.repository.findById(targetId); + if(tar.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find user with id " + targetId); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + User target = tar.get(); + + Friend friend = new Friend(user, target); + this.friendRepository.save(friend); + + ApiResponse response = new ApiResponse<>("success", friend); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } + + + @GetMapping + public ResponseEntity>> readAll() { + List users = this.repository.findAll(); + ApiResponse> response = new ApiResponse<>("success", users); + return new ResponseEntity<>(response, HttpStatus.OK); + } + + @GetMapping("{id}") + public ResponseEntity> readOne (@PathVariable int id) { + Optional use = this.repository.findById(id); + if(use.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find user with id " + id); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + User user = use.get(); + ApiResponse response = new ApiResponse<>("success", user); + return new ResponseEntity<>(response, HttpStatus.OK); + } + + @GetMapping("{id}/like") + ResponseEntity> readOneLike (@PathVariable int id) { + Optional use = this.repository.findById(id); + if(use.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find user with id " + id); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + User user = use.get(); + + List likes = user.getLikes(); + ApiResponse> response = new ApiResponse<>("success", likes); + return new ResponseEntity<>(response, HttpStatus.OK); + } + + @PutMapping("{id}") + public ResponseEntity> update (@PathVariable int id, @RequestBody User userDetails) { + if(userDetails.isInvalid()) { + ApiResponse response = new ApiResponse<>("error", "Could not create a student with the specified parameters."); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + Optional use = this.repository.findById(id); + + if(use.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find student with id " + id); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + + User user = use.get(); + user.setName(userDetails.getName()); + user.setAboutMe(userDetails.getAboutMe()); + ApiResponse response = new ApiResponse<>("success", repository.save(user)); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } + + @DeleteMapping("{id}") + public ResponseEntity> delete (@PathVariable int id) { + Optional use = this.repository.findById(id); + + if(use.isEmpty()) { + ApiResponse response = new ApiResponse<>("error", "Could not find student with id " + id); + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + + User user = use.get(); + this.repository.delete(user); + + ApiResponse response = new ApiResponse<>("success", user); + return new ResponseEntity<>(response, HttpStatus.OK); + } +} diff --git a/src/main/java/com/booleanuk/api/model/ApiResponse.java b/src/main/java/com/booleanuk/api/model/ApiResponse.java new file mode 100644 index 0000000..f5e4fdb --- /dev/null +++ b/src/main/java/com/booleanuk/api/model/ApiResponse.java @@ -0,0 +1,16 @@ +package com.booleanuk.api.model; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ApiResponse { + private String status; + private T data; + + public ApiResponse(String status, T data) { + this.status = status; + this.data = data; + } +} diff --git a/src/main/java/com/booleanuk/api/model/Friend.java b/src/main/java/com/booleanuk/api/model/Friend.java new file mode 100644 index 0000000..4afc86a --- /dev/null +++ b/src/main/java/com/booleanuk/api/model/Friend.java @@ -0,0 +1,42 @@ +package com.booleanuk.api.model; + +import com.fasterxml.jackson.annotation.JsonFormat; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.CreatedDate; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "friends") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class Friend { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @ManyToOne + @JoinColumn(name = "userOneId", nullable = false) + private User u1; + + @ManyToOne + @JoinColumn(name = "userTwoId", nullable = false) + private User u2; + + @CreatedDate + @JsonFormat(pattern = "dd/MM/yy-HH:mm:ss") + private LocalDateTime createdAt; + + + public Friend(User u1, User u2) { + this.u1 = u1; + this.u2 = u2; + this.createdAt = LocalDateTime.now(); + } +} \ No newline at end of file diff --git a/src/main/java/com/booleanuk/api/model/Like.java b/src/main/java/com/booleanuk/api/model/Like.java new file mode 100644 index 0000000..7d8575d --- /dev/null +++ b/src/main/java/com/booleanuk/api/model/Like.java @@ -0,0 +1,42 @@ +package com.booleanuk.api.model; + +import com.fasterxml.jackson.annotation.JsonFormat; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.CreatedDate; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Entity +@Table(name = "likes") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class Like { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @ManyToOne + @JoinColumn(name = "userId", nullable = false) + private User user; + + @ManyToOne + @JoinColumn(name = "likedPost", nullable = false) + private Post likedPost; + + @CreatedDate + @JsonFormat(pattern = "dd/MM/yy-HH:mm:ss") + private LocalDateTime createdAt; + + public Like(User user, Post likedPost) { + this.user = user; + this.likedPost = likedPost; + this.createdAt = LocalDateTime.now(); + } +} diff --git a/src/main/java/com/booleanuk/api/model/Post.java b/src/main/java/com/booleanuk/api/model/Post.java new file mode 100644 index 0000000..0028b7c --- /dev/null +++ b/src/main/java/com/booleanuk/api/model/Post.java @@ -0,0 +1,58 @@ +package com.booleanuk.api.model; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.micrometer.common.util.StringUtils; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.CreatedDate; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "posts") +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class Post { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + public String contents; + public User originalPoster; + + @ManyToOne + @JoinColumn(name = "parentPostId") + public Post parentPost; + + @OneToMany(mappedBy = "parentPost", cascade = CascadeType.ALL) + private List comments; + + @OneToMany(mappedBy = "likedPost", cascade = CascadeType.ALL) + private List likes; + + @CreatedDate + @JsonFormat(pattern = "dd/MM/yy-HH:mm:ss") + private LocalDateTime createdAt; + + + public Post(String contents, User originalPoster, Post parentPost) { + this.contents = contents; + this.originalPoster = originalPoster; + this.parentPost = parentPost; + this.comments = new ArrayList<>(); + likes = new ArrayList<>(); + this.createdAt = LocalDateTime.now(); + } + + public boolean isInvalid() { + return StringUtils.isBlank(contents); + } +} diff --git a/src/main/java/com/booleanuk/api/model/User.java b/src/main/java/com/booleanuk/api/model/User.java new file mode 100644 index 0000000..aecedb5 --- /dev/null +++ b/src/main/java/com/booleanuk/api/model/User.java @@ -0,0 +1,52 @@ +package com.booleanuk.api.model; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.micrometer.common.util.StringUtils; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.CreatedDate; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "users") +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class User { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + private String name; + private String aboutMe; + + @OneToMany(mappedBy = "originalPoster", cascade = CascadeType.ALL, orphanRemoval = true) + private List posts; + + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) + private List likes; + + @CreatedDate + @JsonFormat(pattern = "dd/MM/yy-HH:mm:ss") + private LocalDateTime createdAt; + + public User(String name, String aboutMe) { + this.name = name; + this.aboutMe = aboutMe; + this.posts = new ArrayList<>(); + this.likes = new ArrayList<>(); + this.createdAt = LocalDateTime.now(); + } + + public boolean isInvalid() { + return (StringUtils.isBlank(name) || StringUtils.isBlank(aboutMe)); + } +} diff --git a/src/main/java/com/booleanuk/api/repository/FriendRepository.java b/src/main/java/com/booleanuk/api/repository/FriendRepository.java new file mode 100644 index 0000000..ffdb3ff --- /dev/null +++ b/src/main/java/com/booleanuk/api/repository/FriendRepository.java @@ -0,0 +1,7 @@ +package com.booleanuk.api.repository; + +import com.booleanuk.api.model.Friend; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FriendRepository extends JpaRepository { +} diff --git a/src/main/java/com/booleanuk/api/repository/LikeRepository.java b/src/main/java/com/booleanuk/api/repository/LikeRepository.java new file mode 100644 index 0000000..249d2f5 --- /dev/null +++ b/src/main/java/com/booleanuk/api/repository/LikeRepository.java @@ -0,0 +1,7 @@ +package com.booleanuk.api.repository; + +import com.booleanuk.api.model.Like; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface LikeRepository extends JpaRepository { +} diff --git a/src/main/java/com/booleanuk/api/repository/PostRepository.java b/src/main/java/com/booleanuk/api/repository/PostRepository.java new file mode 100644 index 0000000..a80e468 --- /dev/null +++ b/src/main/java/com/booleanuk/api/repository/PostRepository.java @@ -0,0 +1,7 @@ +package com.booleanuk.api.repository; + +import com.booleanuk.api.model.Post; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { +} diff --git a/src/main/java/com/booleanuk/api/repository/UserRepository.java b/src/main/java/com/booleanuk/api/repository/UserRepository.java new file mode 100644 index 0000000..74858a5 --- /dev/null +++ b/src/main/java/com/booleanuk/api/repository/UserRepository.java @@ -0,0 +1,7 @@ +package com.booleanuk.api.repository; + +import com.booleanuk.api.model.User; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml deleted file mode 100644 index 02c2591..0000000 --- a/src/main/resources/application.yml +++ /dev/null @@ -1,7 +0,0 @@ -server: - port: 4000 - error: - include-message: always - include-binding-errors: always - include-stacktrace: never - include-exception: false From 2b529e52e4c030022ad6b71a8512ae4708176c4d Mon Sep 17 00:00:00 2001 From: Iris Flystam Date: Fri, 20 Sep 2024 08:57:50 +0200 Subject: [PATCH 2/3] Think all the functions work on neondb. Have tested all functions, but not all variations of situations (with/without likes/comments/friends etc) --- .../com/booleanuk/api/controller/PostController.java | 8 ++++---- .../com/booleanuk/api/controller/UserController.java | 1 + src/main/java/com/booleanuk/api/model/Friend.java | 8 ++++++-- src/main/java/com/booleanuk/api/model/Like.java | 4 ++++ src/main/java/com/booleanuk/api/model/Post.java | 10 ++++++++++ src/main/java/com/booleanuk/api/model/User.java | 7 ++++++- .../com/booleanuk/api/repository/FriendRepository.java | 8 ++++++++ 7 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/booleanuk/api/controller/PostController.java b/src/main/java/com/booleanuk/api/controller/PostController.java index 979d620..114f5b5 100644 --- a/src/main/java/com/booleanuk/api/controller/PostController.java +++ b/src/main/java/com/booleanuk/api/controller/PostController.java @@ -60,7 +60,7 @@ public ResponseEntity> createPost (@PathVariable int userId, @Req } @PostMapping("{userId}/{postId}") - public ResponseEntity> createPost (@PathVariable int userId, @PathVariable int postId, @RequestBody Post postDetails) { + public ResponseEntity> createComment (@PathVariable int userId, @PathVariable int postId, @RequestBody Post postDetails) { Optional use = this.userRepository.findById(userId); if(use.isEmpty()) { @@ -167,7 +167,7 @@ public ResponseEntity> readOne (@PathVariable int id) { } @PutMapping("{id}") - public ResponseEntity> update (@PathVariable int id, @RequestBody String newContents) { + public ResponseEntity> update (@PathVariable int id, @RequestBody Post postDetails) { Optional pos = this.postRepository.findById(id); if(pos.isEmpty()) { @@ -177,12 +177,12 @@ public ResponseEntity> update (@PathVariable int id, @RequestBody Post post = pos.get(); - if(StringUtils.isBlank(newContents)) { + if(postDetails.isInvalid()) { ApiResponse response = new ApiResponse<>("error", "Could not create a post with the specified parameters."); return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); } - post.setContents(newContents); + post.setContents(postDetails.getContents()); ApiResponse response = new ApiResponse<>("success", post); return new ResponseEntity<>(response, HttpStatus.CREATED); diff --git a/src/main/java/com/booleanuk/api/controller/UserController.java b/src/main/java/com/booleanuk/api/controller/UserController.java index 51787ae..e02b659 100644 --- a/src/main/java/com/booleanuk/api/controller/UserController.java +++ b/src/main/java/com/booleanuk/api/controller/UserController.java @@ -129,6 +129,7 @@ public ResponseEntity> delete (@PathVariable int id) { } User user = use.get(); + this.friendRepository.deleteAllByUserId(user.getId()); this.repository.delete(user); ApiResponse response = new ApiResponse<>("success", user); diff --git a/src/main/java/com/booleanuk/api/model/Friend.java b/src/main/java/com/booleanuk/api/model/Friend.java index 4afc86a..ff582b8 100644 --- a/src/main/java/com/booleanuk/api/model/Friend.java +++ b/src/main/java/com/booleanuk/api/model/Friend.java @@ -1,6 +1,8 @@ package com.booleanuk.api.model; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Getter; @@ -21,12 +23,14 @@ public class Friend { @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; - @ManyToOne + @ManyToOne(cascade = CascadeType.REMOVE) @JoinColumn(name = "userOneId", nullable = false) + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private User u1; - @ManyToOne + @ManyToOne(cascade = CascadeType.REMOVE) @JoinColumn(name = "userTwoId", nullable = false) + @JsonIgnoreProperties({"aboutMe", "posts", "createdAt"}) private User u2; @CreatedDate diff --git a/src/main/java/com/booleanuk/api/model/Like.java b/src/main/java/com/booleanuk/api/model/Like.java index 7d8575d..c8b0598 100644 --- a/src/main/java/com/booleanuk/api/model/Like.java +++ b/src/main/java/com/booleanuk/api/model/Like.java @@ -1,6 +1,8 @@ package com.booleanuk.api.model; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Getter; @@ -24,10 +26,12 @@ public class Like { @ManyToOne @JoinColumn(name = "userId", nullable = false) + @JsonIgnoreProperties({"aboutMe", "posts", "likes", "createdAt"}) private User user; @ManyToOne @JoinColumn(name = "likedPost", nullable = false) + @JsonIgnoreProperties({"originalPoster", "parentPost", "likes", "comments", "createdAt"}) private Post likedPost; @CreatedDate diff --git a/src/main/java/com/booleanuk/api/model/Post.java b/src/main/java/com/booleanuk/api/model/Post.java index 0028b7c..d07dea1 100644 --- a/src/main/java/com/booleanuk/api/model/Post.java +++ b/src/main/java/com/booleanuk/api/model/Post.java @@ -1,6 +1,9 @@ package com.booleanuk.api.model; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import io.micrometer.common.util.StringUtils; import jakarta.persistence.*; import lombok.AllArgsConstructor; @@ -26,16 +29,22 @@ public class Post { private Integer id; public String contents; + + @ManyToOne + @JoinColumn(name = "originalPosterId") + @JsonIgnoreProperties({"aboutMe", "posts"}) public User originalPoster; @ManyToOne @JoinColumn(name = "parentPostId") + @JsonIgnoreProperties({"originalPoster", "parentPost", "comments", "likes", "createdAt"}) public Post parentPost; @OneToMany(mappedBy = "parentPost", cascade = CascadeType.ALL) private List comments; @OneToMany(mappedBy = "likedPost", cascade = CascadeType.ALL) + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private List likes; @CreatedDate @@ -52,6 +61,7 @@ public Post(String contents, User originalPoster, Post parentPost) { this.createdAt = LocalDateTime.now(); } + @JsonIgnore public boolean isInvalid() { return StringUtils.isBlank(contents); } diff --git a/src/main/java/com/booleanuk/api/model/User.java b/src/main/java/com/booleanuk/api/model/User.java index aecedb5..db4549a 100644 --- a/src/main/java/com/booleanuk/api/model/User.java +++ b/src/main/java/com/booleanuk/api/model/User.java @@ -1,6 +1,9 @@ package com.booleanuk.api.model; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import io.micrometer.common.util.StringUtils; import jakarta.persistence.*; import lombok.AllArgsConstructor; @@ -9,7 +12,6 @@ import lombok.Setter; import org.springframework.data.annotation.CreatedDate; -import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -29,9 +31,11 @@ public class User { private String aboutMe; @OneToMany(mappedBy = "originalPoster", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonIgnoreProperties({"originalPoster", "parentPost", "likes"}) private List posts; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private List likes; @CreatedDate @@ -46,6 +50,7 @@ public User(String name, String aboutMe) { this.createdAt = LocalDateTime.now(); } + @JsonIgnore public boolean isInvalid() { return (StringUtils.isBlank(name) || StringUtils.isBlank(aboutMe)); } diff --git a/src/main/java/com/booleanuk/api/repository/FriendRepository.java b/src/main/java/com/booleanuk/api/repository/FriendRepository.java index ffdb3ff..b3250a9 100644 --- a/src/main/java/com/booleanuk/api/repository/FriendRepository.java +++ b/src/main/java/com/booleanuk/api/repository/FriendRepository.java @@ -1,7 +1,15 @@ package com.booleanuk.api.repository; import com.booleanuk.api.model.Friend; +import jakarta.transaction.Transactional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface FriendRepository extends JpaRepository { + @Modifying + @Transactional + @Query("DELETE FROM Friend f WHERE f.u1.id = :userId OR f.u2.id = :userId") + void deleteAllByUserId(@Param("userId") Integer userId); } From b0096a5e5c8c00a6f792cc7287e7140e59ae2021 Mon Sep 17 00:00:00 2001 From: Iris Flystam Date: Fri, 20 Sep 2024 10:10:26 +0200 Subject: [PATCH 3/3] Program works through docker now. basic and extended exercises --- Dockerfile | 9 +++++++++ build.gradle | 11 +++++++++++ docker-compose.yml | 21 +++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ea842b5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM eclipse-temurin:18 + +WORKDIR /app + +COPY java.docker.day.2-0.0.1.jar /app/java.docker.day.2-0.0.1.jar + +EXPOSE 4000 + +ENTRYPOINT ["java", "-jar", "java.docker.day.2-0.0.1.jar"] \ No newline at end of file diff --git a/build.gradle b/build.gradle index fb070c4..53d5e6c 100644 --- a/build.gradle +++ b/build.gradle @@ -31,3 +31,14 @@ dependencies { tasks.named('test') { useJUnitPlatform() } + +jar { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + manifest { + attributes 'Main-Class': 'com.booleanuk.api.Main' + } + + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9eb38d7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +services: + app: + image: 'test-prog:latest' + container_name: app + depends_on: + - db + ports: + - '4000:4000' + environment: + - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mypostgresuser + - SPRING_DATASOURCE_USERNAME=mypostgresuser + - SPRING_DATASOURCE_PASSWORD=mypostgrespassword + - SPRING_JPA_HIBERNATE_DDL_AUTO=update + + db: + image: 'postgres:latest' + container_name: db + environment: + - POSTGRES_USER=mypostgresuser + - POSTGRES_DATABASE=mypostgresuser + - POSTGRES_PASSWORD=mypostgrespassword \ No newline at end of file