Unverified Commit 59f10286 authored by vky25's avatar vky25 Committed by GitHub
Browse files

Merge pull request #1 from UPHRH-platform/development

Development
No related merge requests found
Showing with 688 additions and 0 deletions
+688 -0
Dockerfile 0 → 100644
FROM openjdk:11
MAINTAINER haridas <haridas.kakunje@tarento.com>
ADD target/comment-hub-0.0.1-SNAPSHOT.jar comment-hub-0.0.1-SNAPSHOT.jar
#ADD public/emails emails
ENTRYPOINT ["java", "-jar", "/comment-hub-0.0.1-SNAPSHOT.jar"]
EXPOSE 8099
version: '3'
services:
comment-hub:
image: comment-hub-dev:1.10
build:
context: .
ports:
- '8099:8099'
pom.xml 0 → 100644
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.15</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tarento</groupId>
<artifactId>comment-hub</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>comment-hub</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.3.4</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<version>1.0.86</version>
<exclusions>
<exclusion>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
<finalName>comment-hub-0.0.1-SNAPSHOT</finalName>
</build>
</project>
package com.tarento.commenthub;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CommentHubApplication {
public static void main(String[] args) {
SpringApplication.run(CommentHubApplication.class, args);
}
}
\ No newline at end of file
package com.tarento.commenthub.config;
import com.tarento.commenthub.entity.Comment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Comment> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Comment> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}
package com.tarento.commenthub.constant;
public class Constants {
private Constants() {
}
public static final String ENTITY_ID = "entityId";
public static final String ENTITY_TYPE = "entityType";
public static final String WORKFLOW = "workflow";
public static final String COMMENT_ID = "commentId";
public static final String COMMENT_TREE_ID = "commentTreeId";
public static final String COMMENT_KEY = "comment_";
public static final String COMMENTS = "comments";
public static final String CHILD_NODES = "childNodes";
public static final String ERROR = "ERROR";
public static final String HIERARCHY_PATH = "hierarchyPath";
public static final String COMMENT_DATA = "commentData";
public static final String COMMENT_TREE_DATA = "commentTreeData";
public static final String CHILDREN = "children";
public static final String FIRST_LEVEL_NODES = "firstLevelNodes";
public static final String COMMENT_SOURCE = "commentSource";
public static final String FILE = "file";
public static final String SUCCESS_STRING = "success";
public static final String DUPLICATE_TREE_ERROR = "DUPLICATE TREE CREATION ERROR";
public static final String DUPLICATE_TREE_ERROR_MESSAGE =
"Failed to create a new comment tree. " +
"A comment tree with the same 'entityType,' 'entityId,' and 'workflow' already exists.";
public static final String WRONG_HIERARCHY_PATH_ERROR = "WRONG HIERARCHY PATH ERROR";
public static final String ADD_FIRST_COMMENT_PAYLOAD_VALIDATION_FILE = "/payloadValidation/firstComment.json";
public static final String ADD_NEW_COMMENT_PAYLOAD_VALIDATION_FILE = "/payloadValidation/newComment.json";
public static final String UPDATE_EXISTING_COMMENT_VALIDATION_FILE = "/payloadValidation/updateComment.json";
public static final String RESOLVED = "resolved";
public static final String COMMENT_RESOLVED = "commentResolved";
public static final String TRUE = "true";
public static final String FALSE = "false";
}
\ No newline at end of file
package com.tarento.commenthub.controller;
import com.fasterxml.jackson.databind.JsonNode;
import com.tarento.commenthub.constant.Constants;
import com.tarento.commenthub.dto.CommentTreeIdentifierDTO;
import com.tarento.commenthub.dto.MultipleWorkflowsCommentResponseDTO;
import com.tarento.commenthub.dto.CommentsResoponseDTO;
import com.tarento.commenthub.dto.ResponseDTO;
import com.tarento.commenthub.entity.Comment;
import com.tarento.commenthub.entity.CommentTree;
import com.tarento.commenthub.service.CommentService;
import com.tarento.commenthub.service.CommentTreeService;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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("/api/v1/comment")
@Slf4j
public class CommentController {
@Autowired
CommentTreeService commentTreeService;
@Autowired
private CommentService commentService;
@PostMapping("/addFirst")
public ResponseDTO addFirstComment(@RequestBody JsonNode payload) {
return commentService.addFirstCommentToCreateTree(payload);
}
@PostMapping("/addNew")
public ResponseDTO addNewComment(@RequestBody JsonNode payload) {
return commentService.addNewCommentToTree(payload);
}
@PutMapping("/update")
public ResponseDTO updateExistingComment(@RequestBody JsonNode payload) {
return commentService.updateExistingComment(payload);
}
@GetMapping("/getAll")
public CommentsResoponseDTO getComments(
@RequestParam(name = "entityType") String entityType,
@RequestParam(name = "entityId") String entityId,
@RequestParam(name = "workflow") String workflow) {
CommentTreeIdentifierDTO commentTreeIdentifierDTO = new CommentTreeIdentifierDTO();
commentTreeIdentifierDTO.setEntityType(entityType);
commentTreeIdentifierDTO.setEntityId(entityId);
commentTreeIdentifierDTO.setWorkflow(workflow);
return commentService.getComments(commentTreeIdentifierDTO);
}
@GetMapping("/multipleWorkflows")
public List<MultipleWorkflowsCommentResponseDTO> getCommentsForMultipleWorkflows(
@RequestParam(name = "entityType") String entityType,
@RequestParam(name = "entityId") String entityId,
@RequestParam(name = "workflow") List<String> workflows) {
return commentService.getComments(entityType, entityId, workflows);
}
@DeleteMapping("/delete/{commentId}")
public Comment deleteComment(
@PathVariable String commentId,
@RequestParam(name = "entityType") String entityType,
@RequestParam(name = "entityId") String entityId,
@RequestParam(name = "workflow") String workflow) {
CommentTreeIdentifierDTO commentTreeIdentifierDTO = new CommentTreeIdentifierDTO();
commentTreeIdentifierDTO.setEntityType(entityType);
commentTreeIdentifierDTO.setEntityId(entityId);
commentTreeIdentifierDTO.setWorkflow(workflow);
return commentService.deleteCommentById(commentId, commentTreeIdentifierDTO);
}
@PostMapping("/setStatusToResolved")
public CommentTree setCommentTreeStatusToResolved(
@RequestParam(name = "entityType") String entityType,
@RequestParam(name = "entityId") String entityId,
@RequestParam(name = "workflow") String workflow) {
CommentTreeIdentifierDTO commentTreeIdentifierDTO = new CommentTreeIdentifierDTO();
commentTreeIdentifierDTO.setEntityType(entityType);
commentTreeIdentifierDTO.setEntityId(entityId);
commentTreeIdentifierDTO.setWorkflow(workflow);
return commentTreeService.setCommentTreeStatusToResolved(commentTreeIdentifierDTO);
}
@PostMapping("/{commentId}/resolve")
public Comment resolveComment(@PathVariable String commentId) {
return commentService.resolveComment(commentId);
}
@GetMapping("/health")
public String healthCheck() {
return Constants.SUCCESS_STRING;
}
}
package com.tarento.commenthub.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class CommentTreeIdentifierDTO {
private String entityType;
private String entityId;
private String workflow;
}
\ No newline at end of file
package com.tarento.commenthub.dto;
import com.tarento.commenthub.entity.Comment;
import com.tarento.commenthub.entity.CommentTree;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class CommentsResoponseDTO {
private CommentTree commentTree;
private List<Comment> comments;
private int commentCount;
}
package com.tarento.commenthub.dto;
import com.tarento.commenthub.entity.Comment;
import com.tarento.commenthub.entity.CommentTree;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class MultipleWorkflowsCommentResponseDTO {
private CommentTree commentTree;
private List<Comment> comments;
private int commentCount;
}
package com.tarento.commenthub.dto;
import com.tarento.commenthub.entity.Comment;
import com.tarento.commenthub.entity.CommentTree;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class ResponseDTO {
private CommentTree commentTree;
private Comment comment;
}
package com.tarento.commenthub.entity;
import com.fasterxml.jackson.databind.JsonNode;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import java.io.Serializable;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.UpdateTimestamp;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "comment")
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
public class Comment implements Serializable {
@Id
private String commentId;
@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
private JsonNode commentData;
@Column(columnDefinition = "varchar(255) default 'active'")
private String status;
private Timestamp createdDate;
private Timestamp lastUpdatedDate;
}
\ No newline at end of file
package com.tarento.commenthub.entity;
import com.fasterxml.jackson.databind.JsonNode;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.UpdateTimestamp;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "comment_tree")
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
public class CommentTree {
@Id
private String commentTreeId;
@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
private JsonNode commentTreeData;
@Column(columnDefinition = "varchar(255) default 'active'")
private String status;
private Timestamp createdDate;
private Timestamp lastUpdatedDate;
}
\ No newline at end of file
package com.tarento.commenthub.exception;
import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Component;
import java.util.Map;
@Getter
@Setter
@Component
public class CommentException extends RuntimeException{
private String code;
private String message;
private String httpStatusCode;
private Map<String, String> errors;
public CommentException() {
}
public CommentException(String code, String message) {
this.code = code;
this.message = message;
}
public CommentException(String code, String message, String httpStatusCode) {
this.code = code;
this.message = message;
this.httpStatusCode = httpStatusCode;
}
public CommentException(Map<String, String> errors) {
this.message = errors.toString();
this.errors = errors;
}
}
\ No newline at end of file
package com.tarento.commenthub.exception;
import java.util.Map;
import lombok.Builder;
import lombok.Value;
@Value
@Builder
public class ErrorResponse {
private String code;
private String message;
private Map<String, String> errors;
private String httpStatusCode;
}
\ No newline at end of file
package com.tarento.commenthub.exception;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
@Slf4j
public class RestExceptionHandling {
@ExceptionHandler(Exception.class)
public ResponseEntity handleException(Exception ex) {
log.debug("RestExceptionHandler::handleException::" + ex);
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
ErrorResponse errorResponse = null;
if (ex instanceof CommentException) {
CommentException commentException = (CommentException) ex;
status = HttpStatus.BAD_REQUEST;
errorResponse = ErrorResponse.builder()
.code(commentException.getCode())
.message(commentException.getMessage())
.httpStatusCode(commentException.getHttpStatusCode() != null
? commentException.getHttpStatusCode()
: String.valueOf(status.value()))
.build();
if (StringUtils.isNotBlank(commentException.getMessage())) {
log.error(commentException.getMessage());
}
return new ResponseEntity<>(errorResponse, status);
}
errorResponse = ErrorResponse.builder()
.code(ex.getMessage()).build();
return new ResponseEntity<>(errorResponse, status);
}
}
\ No newline at end of file
package com.tarento.commenthub.repository;
import com.tarento.commenthub.entity.Comment;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface CommentRepository extends JpaRepository<Comment, String> {
Optional<Comment> findByCommentIdAndStatus(String id, String status);
List<Comment> findByCommentIdInAndStatus(List<String> ids, String status);
List<Comment> findByStatus(String status);
@Query(value = "SELECT created_date FROM comment WHERE comment_id = ?1", nativeQuery = true)
LocalDateTime getCreatedDateByCommentId(String commentId);
}
\ No newline at end of file
package com.tarento.commenthub.repository;
import com.tarento.commenthub.entity.CommentTree;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface CommentTreeRepository extends JpaRepository<CommentTree, String> {
@Query(value = "SELECT * "
+ "FROM comment_tree "
+ "WHERE comment_tree_id IN ("
+ " SELECT comment_tree_id "
+ " FROM comment_tree "
+ " WHERE (comment_tree_data->>'entityId' = :entityId AND comment_tree_data->>'entityType' = :entityType "
+ " AND comment_tree_data->>'workflow' IN (:workflowList))"
+ ")", nativeQuery = true)
List<CommentTree> getAllCommentTreeForMultipleWorkflows(
@Param("entityId") String entityId,
@Param("entityType") String entityType,
@Param("workflowList") List<String> workflowList
);
@Query(value = "SELECT COUNT(*) FROM comment_tree WHERE comment_tree_id = ?1", nativeQuery = true)
int getIdCount(String commentTreeId);
}
\ No newline at end of file
package com.tarento.commenthub.service;
import com.fasterxml.jackson.databind.JsonNode;
import com.tarento.commenthub.dto.CommentTreeIdentifierDTO;
import com.tarento.commenthub.dto.MultipleWorkflowsCommentResponseDTO;
import com.tarento.commenthub.dto.CommentsResoponseDTO;
import com.tarento.commenthub.dto.ResponseDTO;
import com.tarento.commenthub.entity.Comment;
import io.swagger.v3.core.util.Json;
import java.util.List;
public interface CommentService {
ResponseDTO addFirstCommentToCreateTree(JsonNode payload);
ResponseDTO addNewCommentToTree(JsonNode payload);
ResponseDTO updateExistingComment(JsonNode paylaod);
CommentsResoponseDTO getComments(CommentTreeIdentifierDTO commentTreeIdentifierDTO);
List<MultipleWorkflowsCommentResponseDTO> getComments(String entityType, String entityId,
List<String> workflowList);
Comment deleteCommentById(String commentId, CommentTreeIdentifierDTO commentTreeIdentifierDTO);
Comment resolveComment(String commentId);
}
package com.tarento.commenthub.service;
import com.fasterxml.jackson.databind.JsonNode;
import com.tarento.commenthub.dto.CommentTreeIdentifierDTO;
import com.tarento.commenthub.entity.CommentTree;
import java.util.List;
public interface CommentTreeService {
CommentTree createCommentTree(JsonNode payload);
CommentTree updateCommentTree(JsonNode payload);
CommentTree getCommentTreeById(String commentTreeId);
CommentTree getCommentTree(CommentTreeIdentifierDTO commentTreeIdentifierDTO);
void updateCommentTreeForDeletedComment(String commentId,
CommentTreeIdentifierDTO commentTreeIdentifierDTO);
List<CommentTree> getAllCommentTreeForMultipleWorkflows(String entityType, String entityId,
List<String> workflows);
CommentTree setCommentTreeStatusToResolved(CommentTreeIdentifierDTO commentTreeIdentifierDTO);
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment