Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.netty.channel.ChannelOption;
import java.time.Duration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
Expand All @@ -11,21 +12,23 @@
import reactor.netty.http.client.HttpClient;

@Configuration
class ProjectWebClientConfiguration {
public class WebClientConfig {
@Bean
WebClient projectWebClient(WebClient.Builder webClientBuilder) {
WebClient projectWebClient(
WebClient.Builder webClientBuilder, @Value("${app.edge-service.url}") String edgeServiceUrl) {

HttpClient httpClient =
HttpClient.create()
.protocol(HttpProtocol.H2C)
.wiretap(true)
// it is the time we wait to receive a response after sending a
// request.
.responseTimeout(Duration.ofMillis(500))
.responseTimeout(Duration.ofMillis(5_00))
// Period within which a connection between a client and a server must be established
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1_000);
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2_000);

return webClientBuilder
.baseUrl(edgeServiceUrl)
.defaultHeader(HttpHeaders.USER_AGENT, "project-service")
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

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

import java.time.LocalDateTime;
import java.util.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

Expand All @@ -15,14 +14,33 @@ public class IssueEntity {
private Integer priority;
private Integer severity;
private String businessUnit;
private Set<ProjectInfoRef> projects;
private String header;
private String description;
private String reporter;
private String assignee;
private Set<ProjectAttachment> attachments;
private Set<String> watchers;
private Map<String, String> tags;
private String lastUpdateBy;
private LocalDateTime createdAt;
private LocalDateTime endedAt;
private String lastUpdateBy;

@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
public static class ProjectAttachment {
private String projectId;
private String name;
private Version version;
}

@Getter
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
public static class Version {
private String id;
private String version;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.github.devraghav.bugtracker.issue.event;

import com.github.devraghav.bugtracker.issue.event.internal.IssueEvent;
import com.github.devraghav.bugtracker.issue.request.IssueRequest;
import com.github.devraghav.bugtracker.issue.response.IssueResponse;
import com.github.devraghav.data_model.domain.issue.ProjectAttachment;
import com.github.devraghav.data_model.event.issue.IssueCreated;
import com.github.devraghav.data_model.schema.issue.IssueCreatedSchema;
import java.time.ZoneOffset;
Expand All @@ -13,14 +11,16 @@

class IssueCreatedEventConverter implements EventConverter<IssueEvent.Created, IssueCreatedSchema> {

private ProjectAttachment getProject(IssueRequest.ProjectInfo project) {
return ProjectAttachment.newBuilder()
private com.github.devraghav.data_model.domain.issue.ProjectAttachment getProject(
IssueResponse.ProjectAttachment project) {
return com.github.devraghav.data_model.domain.issue.ProjectAttachment.newBuilder()
.setProjectId(project.projectId())
.setProjectVersionId(project.versionId())
.setProjectVersionId(project.version().id())
.build();
}

private List<ProjectAttachment> getProjects(Set<IssueRequest.ProjectInfo> projects) {
private List<com.github.devraghav.data_model.domain.issue.ProjectAttachment> getProjects(
Set<IssueResponse.ProjectAttachment> projects) {
return projects.stream().map(this::getProject).collect(Collectors.toList());
}

Expand All @@ -34,7 +34,7 @@ private com.github.devraghav.data_model.domain.issue.Issue getIssue(IssueRespons
.setPriority(issue.priority().name())
.setSeverity(issue.severity().name())
.setAssignee(issue.assignee())
.setProjects(getProjects(issue.projects()))
.setProjects(getProjects(issue.attachments()))
.setWatchers(List.copyOf(issue.watchers()))
.setReporter(issue.reporter())
.setTags(issue.tags())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.github.devraghav.bugtracker.issue.event;

import com.github.devraghav.bugtracker.issue.event.internal.IssueEvent;
import com.github.devraghav.bugtracker.issue.request.IssueRequest;
import com.github.devraghav.bugtracker.issue.response.IssueResponse;
import com.github.devraghav.data_model.domain.issue.ProjectAttachment;
import com.github.devraghav.data_model.event.issue.IssueUpdated;
import com.github.devraghav.data_model.schema.issue.IssueUpdatedSchema;
import java.time.ZoneOffset;
Expand All @@ -13,14 +11,16 @@

class IssueUpdatedEventConverter implements EventConverter<IssueEvent.Updated, IssueUpdatedSchema> {

private ProjectAttachment getProject(IssueRequest.ProjectInfo project) {
return ProjectAttachment.newBuilder()
private com.github.devraghav.data_model.domain.issue.ProjectAttachment getProject(
IssueResponse.ProjectAttachment project) {
return com.github.devraghav.data_model.domain.issue.ProjectAttachment.newBuilder()
.setProjectId(project.projectId())
.setProjectVersionId(project.versionId())
.setProjectVersionId(project.version().id())
.build();
}

private List<ProjectAttachment> getProjects(Set<IssueRequest.ProjectInfo> projects) {
private List<com.github.devraghav.data_model.domain.issue.ProjectAttachment> getProjects(
Set<IssueResponse.ProjectAttachment> projects) {
return projects.stream().map(this::getProject).collect(Collectors.toList());
}

Expand All @@ -34,7 +34,7 @@ private com.github.devraghav.data_model.domain.issue.Issue getIssue(IssueRespons
.setPriority(issue.priority().name())
.setSeverity(issue.severity().name())
.setAssignee(issue.assignee())
.setProjects(getProjects(issue.projects()))
.setProjects(getProjects(issue.attachments()))
.setWatchers(List.copyOf(issue.watchers()))
.setReporter(issue.reporter())
.setTags(issue.tags())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ public static ProjectClientException invalidProject(String projectId) {
return new ProjectClientException("Project not found", Map.of("projectId", projectId));
}

public static ProjectClientException invalidProjectOrVersion(String projectId, String versionId) {
return new ProjectClientException(
"Either project or version not found",
Map.of("projectId", projectId, "versionId", versionId));
public static ProjectClientException invalidVersion(String versionId) {
return new ProjectClientException("Version not found", Map.of("versionId", versionId));
}

public static ProjectClientException unableToConnect(WebClientRequestException exception) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.github.devraghav.bugtracker.issue.exception;

import java.util.Map;
import lombok.Getter;
import org.springframework.web.reactive.function.client.WebClientRequestException;

public class UserClientException extends RuntimeException {
@Getter private final Map<String, Object> meta;

private UserClientException(String message, Map<String, Object> meta) {
super(message);
this.meta = meta;
}

public static UserClientException invalidUser(String userId) {
return new UserClientException("User not found", Map.of("userId", userId));
}

public static UserClientException unableToConnect(WebClientRequestException exception) {
return new UserClientException(
"Unable to connect with Project Service", Map.of("path", exception.getUri().getPath()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ private IssueException(String message) {
this(message, Map.of());
}

public static IssueException invalidComment(String content) {
return new IssueException(
"Comment should not be null & less than 256 character length", Map.of("comment", content));
}

public static IssueException nullSeverity() {
return new IssueException("Severity not found");
}
Expand Down Expand Up @@ -58,10 +53,10 @@ public static IssueException noProjectAttach() {
return new IssueException("No project attached");
}

public static IssueException invalidProject(IssueRequest.ProjectInfo projectInfo) {
public static IssueException invalidProject(IssueRequest.ProjectAttachment projectAttachment) {
var meta = new HashMap<String, Object>();
meta.put("projectId", projectInfo.projectId());
meta.put("versionId", projectInfo.versionId());
meta.put("projectId", projectAttachment.projectId());
meta.put("versionId", projectAttachment.versionId());
return new IssueException("Either projectId or versionId is invalid", meta);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.github.devraghav.bugtracker.issue.mapper;

import com.github.devraghav.bugtracker.issue.dto.*;
import com.github.devraghav.bugtracker.issue.entity.IssueEntity;
import com.github.devraghav.bugtracker.issue.project.ProjectResponse;
import com.github.devraghav.bugtracker.issue.request.IssueRequest;
import com.github.devraghav.bugtracker.issue.response.IssueResponse;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import org.mapstruct.*;
import reactor.util.function.Tuple2;

@Mapper(
componentModel = "spring",
Expand Down Expand Up @@ -35,9 +39,33 @@ public interface IssueMapper {
@Mapping(target = "watchers", expression = "java(Set.of())"),
@Mapping(target = "lastUpdateBy", source = "reporter"),
@Mapping(target = "assignee", ignore = true),
@Mapping(target = "endedAt", ignore = true)
@Mapping(target = "endedAt", ignore = true),
@Mapping(target = "attachments", source = "attachments", qualifiedByName = "convertAttachment")
})
IssueEntity issueRequestToIssueEntity(String reporter, IssueRequest.CreateIssue createIssue);
IssueEntity issueRequestToIssueEntity(
String reporter,
IssueRequest.CreateIssue createIssue,
List<Tuple2<ProjectResponse.Project, ProjectResponse.Project.Version>> attachments);

@Named("convertAttachment")
default Set<IssueEntity.ProjectAttachment> convertAttachment(
List<Tuple2<ProjectResponse.Project, ProjectResponse.Project.Version>> attachments) {

return attachments.stream().map(this::getProjectAttachment).collect(Collectors.toSet());
}

private IssueEntity.ProjectAttachment getProjectAttachment(
Tuple2<ProjectResponse.Project, ProjectResponse.Project.Version> tuple2) {
return IssueEntity.ProjectAttachment.builder()
.projectId(tuple2.getT1().id())
.name(tuple2.getT1().name())
.version(
IssueEntity.Version.builder()
.id(tuple2.getT2().id())
.version(tuple2.getT2().version())
.build())
.build();
}

@Mappings({
@Mapping(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.github.devraghav.bugtracker.issue.project;

import com.github.devraghav.bugtracker.issue.exception.ProjectClientException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientRequestException;
import reactor.core.publisher.Mono;

@Component
class DefaultProjectClient implements ProjectClient {
private final WebClient webClient;

public DefaultProjectClient(WebClient webClient) {
this.webClient = webClient;
}

@Override
public Mono<ProjectResponse.Project> getProjectById(String projectId) {
return webClient
.get()
.uri("/api/rest/internal/v1/project/{projectId}", projectId)
.retrieve()
.onStatus(
httpStatusCode -> httpStatusCode.value() == HttpStatus.NOT_FOUND.value(),
clientResponse -> Mono.error(ProjectClientException.invalidProject(projectId)))
.bodyToMono(ProjectResponse.Project.class)
.onErrorResume(
WebClientRequestException.class,
exception -> Mono.error(ProjectClientException.unableToConnect(exception)));
}

@Override
public Mono<ProjectResponse.Project.Version> getVersionById(String projectId, String versionId) {
return webClient
.get()
.uri("/api/rest/internal/v1/project/{projectId}/version/{versionId}", projectId, versionId)
.retrieve()
.onStatus(
httpStatusCode -> httpStatusCode.value() == HttpStatus.NOT_FOUND.value(),
clientResponse -> Mono.error(ProjectClientException.invalidVersion(versionId)))
.bodyToMono(ProjectResponse.Project.Version.class)
.onErrorResume(
WebClientRequestException.class,
exception -> Mono.error(ProjectClientException.unableToConnect(exception)));
}
}
Loading