Source code for Lightrun articles
This commit is contained in:
33
lightrun/api-service/.gitignore
vendored
Normal file
33
lightrun/api-service/.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
45
lightrun/api-service/pom.xml
Normal file
45
lightrun/api-service/pom.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?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.6.7</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>api-service</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>api-service</name>
|
||||
<description>Aggregator Service for LightRun Article</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.apiservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class ApiServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ApiServiceApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.apiservice;
|
||||
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class RequestIdGenerator implements HandlerInterceptor {
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
String requestId = UUID.randomUUID().toString();
|
||||
|
||||
MDC.put(RequestIdGenerator.class.getCanonicalName(), requestId);
|
||||
response.addHeader("X-Request-Id", requestId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||
MDC.remove(RequestIdGenerator.class.getCanonicalName());
|
||||
}
|
||||
|
||||
public static String getRequestId() {
|
||||
return MDC.get(RequestIdGenerator.class.getCanonicalName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.apiservice;
|
||||
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Configuration
|
||||
public class RestTemplateConfig {
|
||||
@Bean
|
||||
public RestTemplate restTemplate(RestTemplateBuilder builder) {
|
||||
return builder
|
||||
.additionalInterceptors((request, body, execution) -> {
|
||||
request.getHeaders().add("X-Request-Id", RequestIdGenerator.getRequestId());
|
||||
|
||||
return execution.execute(request, body);
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.apiservice;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
@Autowired
|
||||
private RequestIdGenerator requestIdGenerator;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(requestIdGenerator);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.apiservice.adapters.http;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public record TaskResponse(String id,
|
||||
String title,
|
||||
Instant created,
|
||||
UserResponse createdBy,
|
||||
UserResponse assignedTo,
|
||||
String status) {
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.baeldung.apiservice.adapters.http;
|
||||
|
||||
import com.baeldung.apiservice.adapters.tasks.Task;
|
||||
import com.baeldung.apiservice.adapters.tasks.TaskRepository;
|
||||
import com.baeldung.apiservice.adapters.users.UserRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RequestMapping("/")
|
||||
@RestController
|
||||
public class TasksController {
|
||||
@Autowired
|
||||
private TaskRepository taskRepository;
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public TaskResponse getTaskById(@PathVariable("id") String id) {
|
||||
Task task = taskRepository.getTaskById(id);
|
||||
|
||||
if (task == null) {
|
||||
throw new UnknownTaskException();
|
||||
}
|
||||
|
||||
return buildResponse(task);
|
||||
}
|
||||
|
||||
private TaskResponse buildResponse(Task task) {
|
||||
return new TaskResponse(task.id(),
|
||||
task.title(),
|
||||
task.created(),
|
||||
getUser(task.createdBy()),
|
||||
getUser(task.assignedTo()),
|
||||
task.status());
|
||||
}
|
||||
|
||||
private UserResponse getUser(String userId) {
|
||||
if (userId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var user = userRepository.getUserById(userId);
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new UserResponse(user.id(), user.name());
|
||||
}
|
||||
@ExceptionHandler(UnknownTaskException.class)
|
||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||
public void handleUnknownTask() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.baeldung.apiservice.adapters.http;
|
||||
|
||||
public class UnknownTaskException extends RuntimeException {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.baeldung.apiservice.adapters.http;
|
||||
|
||||
public record UserResponse(String id, String name) {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.apiservice.adapters.tasks;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public record Task(String id,
|
||||
String title,
|
||||
Instant created,
|
||||
String createdBy,
|
||||
String assignedTo,
|
||||
String status) {
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.baeldung.apiservice.adapters.tasks;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
@Repository
|
||||
public class TaskRepository {
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Value("${tasks-service.url}")
|
||||
private String tasksService;
|
||||
|
||||
public Task getTaskById(String id) {
|
||||
var uri = UriComponentsBuilder.fromUriString(tasksService)
|
||||
.path(id)
|
||||
.build()
|
||||
.toUri();
|
||||
|
||||
try {
|
||||
return restTemplate.getForObject(uri, Task.class);
|
||||
} catch (HttpClientErrorException.NotFound e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.baeldung.apiservice.adapters.users;
|
||||
|
||||
public record User(String id, String name) {
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.apiservice.adapters.users;
|
||||
|
||||
import com.baeldung.apiservice.adapters.users.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
@Repository
|
||||
public class UserRepository {
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Value("${users-service.url}")
|
||||
private String usersService;
|
||||
|
||||
public User getUserById(String id) {
|
||||
var uri = UriComponentsBuilder.fromUriString(usersService)
|
||||
.path(id)
|
||||
.build()
|
||||
.toUri();
|
||||
|
||||
try {
|
||||
return restTemplate.getForObject(uri, User.class);
|
||||
} catch (HttpClientErrorException.NotFound e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
users-service.url=http://localhost:8081
|
||||
tasks-service.url=http://localhost:8082
|
||||
Reference in New Issue
Block a user