Compare commits
1 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
|
4f1fa86833
|
@@ -0,0 +1,24 @@
|
|||||||
|
plugins {
|
||||||
|
id("java")
|
||||||
|
alias(libs.plugins.spring.boot)
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "ua.com.dxrkness"
|
||||||
|
version = "1.0-SNAPSHOT"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// spring
|
||||||
|
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
|
||||||
|
implementation(platform(libs.spring.cloud.dependencies))
|
||||||
|
implementation("org.springframework.cloud:spring-cloud-starter-gateway-server-webflux")
|
||||||
|
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client")
|
||||||
|
implementation("org.springframework.cloud:spring-cloud-starter-loadbalancer")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package ua.com.dxrkness.gateway;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class ApiGatewayApplication {
|
||||||
|
static void main(String[] args) {
|
||||||
|
SpringApplication.run(ApiGatewayApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
server:
|
||||||
|
port: 8079
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
gateway:
|
||||||
|
server:
|
||||||
|
webflux:
|
||||||
|
discovery:
|
||||||
|
locator:
|
||||||
|
enabled: true
|
||||||
|
lower-case-service-id: true
|
||||||
|
application:
|
||||||
|
name: api-gateway
|
||||||
|
eureka:
|
||||||
|
client:
|
||||||
|
service-url:
|
||||||
|
defaultZone: http://localhost:8070/eureka
|
||||||
|
register-with-eureka: false
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
plugins {
|
||||||
|
id("java")
|
||||||
|
alias(libs.plugins.spring.boot)
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "ua.com.dxrkness"
|
||||||
|
version = "1.0-SNAPSHOT"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// spring
|
||||||
|
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
|
||||||
|
implementation(platform(libs.spring.cloud.dependencies))
|
||||||
|
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-server")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package ua.com.dxrkness;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableEurekaServer
|
||||||
|
public class EurekaServerApplication {
|
||||||
|
static void main(String[] args) {
|
||||||
|
SpringApplication.run(EurekaServerApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
server:
|
||||||
|
port: 8070
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: eureka-server
|
||||||
|
eureka:
|
||||||
|
instance:
|
||||||
|
hostname: localhost
|
||||||
|
client:
|
||||||
|
register-with-eureka: false
|
||||||
|
fetch-registry: false
|
||||||
@@ -13,6 +13,8 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
// spring
|
// spring
|
||||||
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
|
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
|
||||||
|
implementation(platform(libs.spring.cloud.dependencies))
|
||||||
|
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client")
|
||||||
implementation(libs.spring.boot.starter.web)
|
implementation(libs.spring.boot.starter.web)
|
||||||
implementation(libs.spring.boot.starter.web.test)
|
implementation(libs.spring.boot.starter.web.test)
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import ua.com.dxrkness.dto.FreightRequest;
|
|
||||||
import ua.com.dxrkness.model.Freight;
|
import ua.com.dxrkness.model.Freight;
|
||||||
import ua.com.dxrkness.service.FreightService;
|
import ua.com.dxrkness.service.FreightService;
|
||||||
|
|
||||||
@@ -75,8 +74,8 @@ public class FreightController {
|
|||||||
description = "Invalid freight data (e.g., weight exceeds vehicle capacity)"
|
description = "Invalid freight data (e.g., weight exceeds vehicle capacity)"
|
||||||
)
|
)
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public Freight add(@RequestBody FreightRequest newFreight) {
|
public Freight add(@RequestBody Freight newFreight) {
|
||||||
return service.add(newFreight.toEntity());
|
return service.add(newFreight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
@@ -92,8 +91,8 @@ public class FreightController {
|
|||||||
description = "Invalid input"
|
description = "Invalid input"
|
||||||
)
|
)
|
||||||
@PutMapping("/{id}")
|
@PutMapping("/{id}")
|
||||||
public Freight update(@PathVariable("id") long id, @RequestBody FreightRequest newFreight) {
|
public Freight update(@PathVariable("id") long id, @RequestBody Freight newFreight) {
|
||||||
return service.update(id, newFreight.toEntity());
|
return service.update(id, newFreight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
@@ -109,8 +108,8 @@ public class FreightController {
|
|||||||
description = "Invalid input"
|
description = "Invalid input"
|
||||||
)
|
)
|
||||||
@PatchMapping("/{id}")
|
@PatchMapping("/{id}")
|
||||||
public Freight updatePatch(@PathVariable("id") long id, @RequestBody FreightRequest newFreight) {
|
public Freight updatePatch(@PathVariable("id") long id, @RequestBody Freight newFreight) {
|
||||||
return service.update(id, newFreight.toEntity());
|
return service.update(id, newFreight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
|
|||||||
@@ -3,3 +3,7 @@ spring:
|
|||||||
name: freight-service
|
name: freight-service
|
||||||
server:
|
server:
|
||||||
port: 8080
|
port: 8080
|
||||||
|
eureka:
|
||||||
|
client:
|
||||||
|
service-url:
|
||||||
|
defaultZone: http://localhost:8070/eureka
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ jspecify = "1.0.0"
|
|||||||
springdoc = "3.0.0"
|
springdoc = "3.0.0"
|
||||||
apache-http-client = "4.5.14"
|
apache-http-client = "4.5.14"
|
||||||
json-schema-validator = "3.0.0"
|
json-schema-validator = "3.0.0"
|
||||||
|
spring-cloud = "2025.1.0"
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot-plugin" }
|
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot-plugin" }
|
||||||
@@ -15,6 +16,7 @@ spring-boot-starter-web = { group = "org.springframework.boot", name = "spring-b
|
|||||||
spring-boot-starter-web-test = { group = "org.springframework.boot", name = "spring-boot-starter-webmvc-test" }
|
spring-boot-starter-web-test = { group = "org.springframework.boot", name = "spring-boot-starter-webmvc-test" }
|
||||||
spring-boot-starter-hateoas = { group = "org.springframework.boot", name = "spring-boot-starter-hateoas" }
|
spring-boot-starter-hateoas = { group = "org.springframework.boot", name = "spring-boot-starter-hateoas" }
|
||||||
spring-boot-devtools = { group = "org.springframework.boot", name = "spring-boot-devtools" }
|
spring-boot-devtools = { group = "org.springframework.boot", name = "spring-boot-devtools" }
|
||||||
|
spring-cloud-dependencies = { group = "org.springframework.cloud", name = "spring-cloud-dependencies", version.ref = "spring-cloud" }
|
||||||
|
|
||||||
# http client
|
# http client
|
||||||
apache-http-client = { group = "org.apache.httpcomponents", name = "httpclient", version.ref = "apache-http-client" }
|
apache-http-client = { group = "org.apache.httpcomponents", name = "httpclient", version.ref = "apache-http-client" }
|
||||||
@@ -25,6 +27,7 @@ springdoc-openapi-starter-webmvc-ui = { group = "org.springdoc", name = "springd
|
|||||||
# jackson
|
# jackson
|
||||||
jackson-dataformat-xml = { group = "tools.jackson.dataformat", name = "jackson-dataformat-xml" }
|
jackson-dataformat-xml = { group = "tools.jackson.dataformat", name = "jackson-dataformat-xml" }
|
||||||
oldjackson-databind = { group = "com.fasterxml.jackson.core", name = "jackson-databind" }
|
oldjackson-databind = { group = "com.fasterxml.jackson.core", name = "jackson-databind" }
|
||||||
|
oldjackson-dataformat-xml = { group = "com.fasterxml.jackson.dataformat", name = "jackson-dataformat-xml" }
|
||||||
|
|
||||||
# testing
|
# testing
|
||||||
junit-bom = { group = "org.junit", name = "junit-bom", version.ref = "junit" }
|
junit-bom = { group = "org.junit", name = "junit-bom", version.ref = "junit" }
|
||||||
|
|||||||
@@ -16,5 +16,6 @@ dependencies {
|
|||||||
|
|
||||||
// jackson
|
// jackson
|
||||||
api(libs.jackson.dataformat.xml)
|
api(libs.jackson.dataformat.xml)
|
||||||
|
api(libs.oldjackson.dataformat.xml)
|
||||||
implementation(libs.oldjackson.databind)
|
implementation(libs.oldjackson.databind)
|
||||||
}
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package ua.com.dxrkness.dto;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonNaming;
|
|
||||||
import ua.com.dxrkness.model.Freight;
|
|
||||||
|
|
||||||
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
|
|
||||||
@tools.jackson.databind.annotation.JsonNaming(tools.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy.class)
|
|
||||||
public record FreightRequest(
|
|
||||||
String name,
|
|
||||||
String description,
|
|
||||||
int weightKg,
|
|
||||||
Freight.Dimensions dimensions,
|
|
||||||
Freight.Status status
|
|
||||||
) {
|
|
||||||
public Freight toEntity() {
|
|
||||||
return new Freight(0, name, description, weightKg, dimensions, status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package ua.com.dxrkness.dto;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonNaming;
|
|
||||||
import ua.com.dxrkness.model.Route;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
|
|
||||||
@tools.jackson.databind.annotation.JsonNaming(tools.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy.class)
|
|
||||||
public record RouteRequest(long vehicleId,
|
|
||||||
List<Long> freightId,
|
|
||||||
String startLocation,
|
|
||||||
String endLocation,
|
|
||||||
Double distanceKm,
|
|
||||||
Double estimatedDurationHours,
|
|
||||||
Route.Status status) {
|
|
||||||
public Route toEntity() {
|
|
||||||
return new Route(0, vehicleId, freightId, startLocation, endLocation, distanceKm, estimatedDurationHours, status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package ua.com.dxrkness.dto;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonNaming;
|
|
||||||
import ua.com.dxrkness.model.Vehicle;
|
|
||||||
|
|
||||||
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
|
|
||||||
@tools.jackson.databind.annotation.JsonNaming(tools.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy.class)
|
|
||||||
public record VehicleRequest(
|
|
||||||
String brand,
|
|
||||||
String model,
|
|
||||||
String licensePlate,
|
|
||||||
int year,
|
|
||||||
int capacityKg,
|
|
||||||
Vehicle.Status status
|
|
||||||
) {
|
|
||||||
public Vehicle toEntity() {
|
|
||||||
return new Vehicle(0, brand, model, licensePlate, year, capacityKg, status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+6
-5
@@ -51,22 +51,22 @@ function publish_correct
|
|||||||
}'
|
}'
|
||||||
|
|
||||||
printf '\n\n'
|
printf '\n\n'
|
||||||
curl -X POST http://localhost:8081/vehicles \
|
curl -X POST http://localhost:8079/vehicle-service/vehicles \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d $vehicle
|
-d $vehicle
|
||||||
|
|
||||||
printf '\n\n'
|
printf '\n\n'
|
||||||
curl -X POST http://localhost:8080/freights \
|
curl -X POST http://localhost:8079/freight-service/freights \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d $freight1
|
-d $freight1
|
||||||
|
|
||||||
printf '\n\n'
|
printf '\n\n'
|
||||||
curl -X POST http://localhost:8080/freights \
|
curl -X POST http://localhost:8079/freight-service/freights \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d $freight2
|
-d $freight2
|
||||||
|
|
||||||
printf '\n\n'
|
printf '\n\n'
|
||||||
curl -X POST http://localhost:8082/routes \
|
curl -X POST http://localhost:8079/route-service/routes \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d $route
|
-d $route
|
||||||
end
|
end
|
||||||
@@ -86,7 +86,8 @@ function add_invalid_route
|
|||||||
"status": "PLANNED"
|
"status": "PLANNED"
|
||||||
}'
|
}'
|
||||||
|
|
||||||
curl -X POST http://localhost:8082/routes \
|
# 404 status is expected, since vehicle svc propagates it's error code to route svc
|
||||||
|
curl -X POST http://localhost:8082/routes \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d $route
|
-d $route
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
// spring
|
// spring
|
||||||
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
|
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
|
||||||
|
implementation(platform(libs.spring.cloud.dependencies))
|
||||||
|
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client")
|
||||||
|
implementation("org.springframework.cloud:spring-cloud-starter-loadbalancer")
|
||||||
implementation(libs.spring.boot.starter.web)
|
implementation(libs.spring.boot.starter.web)
|
||||||
implementation(libs.spring.boot.starter.web.test)
|
implementation(libs.spring.boot.starter.web.test)
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package ua.com.dxrkness.client;
|
|||||||
|
|
||||||
import com.networknt.schema.InputFormat;
|
import com.networknt.schema.InputFormat;
|
||||||
import com.networknt.schema.Schema;
|
import com.networknt.schema.Schema;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.http.HttpStatusCode;
|
import org.springframework.http.HttpStatusCode;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.ErrorResponseException;
|
|
||||||
import org.springframework.web.client.RestClient;
|
import org.springframework.web.client.RestClient;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
import tools.jackson.core.type.TypeReference;
|
import tools.jackson.core.type.TypeReference;
|
||||||
@@ -20,8 +20,8 @@ public class FreightClient {
|
|||||||
private final Schema freightSchema;
|
private final Schema freightSchema;
|
||||||
private final JsonMapper mapper = JsonMapper.shared();
|
private final JsonMapper mapper = JsonMapper.shared();
|
||||||
|
|
||||||
public FreightClient(RestClient freightRestClient, Schema freightSchema) {
|
public FreightClient(@Qualifier("freightRestClient") RestClient.Builder freightRestClient, Schema freightSchema) {
|
||||||
this.freightRestClient = freightRestClient;
|
this.freightRestClient = freightRestClient.build();
|
||||||
this.freightSchema = freightSchema;
|
this.freightSchema = freightSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package ua.com.dxrkness.client;
|
|||||||
import com.networknt.schema.Error;
|
import com.networknt.schema.Error;
|
||||||
import com.networknt.schema.InputFormat;
|
import com.networknt.schema.InputFormat;
|
||||||
import com.networknt.schema.Schema;
|
import com.networknt.schema.Schema;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.http.HttpStatusCode;
|
import org.springframework.http.HttpStatusCode;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -20,8 +21,8 @@ public class VehicleClient {
|
|||||||
private final Schema vehicleSchema;
|
private final Schema vehicleSchema;
|
||||||
private final JsonMapper mapper = JsonMapper.shared();
|
private final JsonMapper mapper = JsonMapper.shared();
|
||||||
|
|
||||||
public VehicleClient(RestClient vehicleRestClient, Schema vehicleSchema) {
|
public VehicleClient(@Qualifier("vehicleRestClient") RestClient.Builder vehicleRestClient, Schema vehicleSchema) {
|
||||||
this.vehicleRestClient = vehicleRestClient;
|
this.vehicleRestClient = vehicleRestClient.build();
|
||||||
this.vehicleSchema = vehicleSchema;
|
this.vehicleSchema = vehicleSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,28 @@
|
|||||||
package ua.com.dxrkness.config;
|
package ua.com.dxrkness.config;
|
||||||
|
|
||||||
|
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.web.client.RestClient;
|
import org.springframework.web.client.RestClient;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class ClientConfiguration {
|
public class ClientConfiguration {
|
||||||
@Bean
|
@Bean
|
||||||
public RestClient vehicleRestClient() {
|
@LoadBalanced
|
||||||
return RestClient.create("http://localhost:8081/vehicles");
|
public RestClient.Builder vehicleRestClient() {
|
||||||
|
return RestClient.builder().baseUrl("http://vehicle-service/vehicles");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RestClient freightRestClient() {
|
@LoadBalanced
|
||||||
return RestClient.create("http://localhost:8080/freights");
|
public RestClient.Builder freightRestClient() {
|
||||||
|
return RestClient.builder().baseUrl("http://freight-service/freights");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Primary
|
||||||
|
public RestClient.Builder defaultRestClient() {
|
||||||
|
return RestClient.builder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import org.springframework.http.MediaType;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import ua.com.dxrkness.client.FreightClient;
|
import ua.com.dxrkness.client.FreightClient;
|
||||||
import ua.com.dxrkness.client.VehicleClient;
|
import ua.com.dxrkness.client.VehicleClient;
|
||||||
import ua.com.dxrkness.dto.RouteRequest;
|
|
||||||
import ua.com.dxrkness.model.Freight;
|
import ua.com.dxrkness.model.Freight;
|
||||||
import ua.com.dxrkness.model.Route;
|
import ua.com.dxrkness.model.Route;
|
||||||
import ua.com.dxrkness.model.Vehicle;
|
import ua.com.dxrkness.model.Vehicle;
|
||||||
@@ -154,8 +153,8 @@ public class RouteController {
|
|||||||
description = "Route object to be created. Must include valid vehicleId and freightId list.",
|
description = "Route object to be created. Must include valid vehicleId and freightId list.",
|
||||||
required = true
|
required = true
|
||||||
)
|
)
|
||||||
@RequestBody RouteRequest newRoute) {
|
@RequestBody Route newRoute) {
|
||||||
return routeService.add(newRoute.toEntity());
|
return routeService.add(newRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
@@ -178,8 +177,8 @@ public class RouteController {
|
|||||||
description = "Updated route object",
|
description = "Updated route object",
|
||||||
required = true
|
required = true
|
||||||
)
|
)
|
||||||
@RequestBody RouteRequest newRoute) {
|
@RequestBody Route newRoute) {
|
||||||
return routeService.update(id, newRoute.toEntity());
|
return routeService.update(id, newRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
@@ -202,8 +201,8 @@ public class RouteController {
|
|||||||
description = "Route object with fields to update",
|
description = "Route object with fields to update",
|
||||||
required = true
|
required = true
|
||||||
)
|
)
|
||||||
@RequestBody RouteRequest newRoute) {
|
@RequestBody Route newRoute) {
|
||||||
return routeService.update(id, newRoute.toEntity());
|
return routeService.update(id, newRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: route-service
|
name: route-service
|
||||||
|
cloud:
|
||||||
|
loadbalancer:
|
||||||
|
cache:
|
||||||
|
enabled: false
|
||||||
server:
|
server:
|
||||||
port: 8082
|
port: 8082
|
||||||
|
eureka:
|
||||||
|
client:
|
||||||
|
service-url:
|
||||||
|
defaultZone: http://localhost:8070/eureka
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
rootProject.name = "itroi"
|
rootProject.name = "itroi"
|
||||||
enableFeaturePreview("STABLE_CONFIGURATION_CACHE")
|
enableFeaturePreview("STABLE_CONFIGURATION_CACHE")
|
||||||
|
|
||||||
include("models", "vehicle-service", "route-service", "freight-service", "shared")
|
include("models", "vehicle-service", "route-service", "freight-service", "shared", "api-gateway", "eureka-server")
|
||||||
@@ -7,11 +7,8 @@ import org.apache.http.impl.client.HttpClients;
|
|||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import tools.jackson.databind.ObjectMapper;
|
import tools.jackson.databind.json.JsonMapper;
|
||||||
import tools.jackson.dataformat.xml.XmlMapper;
|
import tools.jackson.dataformat.xml.XmlMapper;
|
||||||
import ua.com.dxrkness.dto.FreightRequest;
|
|
||||||
import ua.com.dxrkness.dto.RouteRequest;
|
|
||||||
import ua.com.dxrkness.dto.VehicleRequest;
|
|
||||||
import ua.com.dxrkness.model.Freight;
|
import ua.com.dxrkness.model.Freight;
|
||||||
import ua.com.dxrkness.model.Route;
|
import ua.com.dxrkness.model.Route;
|
||||||
import ua.com.dxrkness.model.Vehicle;
|
import ua.com.dxrkness.model.Vehicle;
|
||||||
@@ -19,11 +16,9 @@ import ua.com.dxrkness.model.Vehicle;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ApplicationClient {
|
public class ApplicationClient {
|
||||||
private static final String FREIGHTS_BASE_URL = "http://localhost:8080";
|
private static final String BASE_URL = "http://localhost:8079";
|
||||||
private static final String VEHICLES_BASE_URL = "http://localhost:8081";
|
private static final JsonMapper jsonMapper = JsonMapper.builder().build();
|
||||||
private static final String ROUTES_BASE_URL = "http://localhost:8082";
|
private static final XmlMapper xmlMapper = XmlMapper.builder().build();
|
||||||
private static final ObjectMapper jsonMapper = new ObjectMapper();
|
|
||||||
private static final XmlMapper xmlMapper = new XmlMapper();
|
|
||||||
|
|
||||||
static void main() {
|
static void main() {
|
||||||
try (CloseableHttpClient client = HttpClients.createDefault()) {
|
try (CloseableHttpClient client = HttpClients.createDefault()) {
|
||||||
@@ -36,176 +31,170 @@ public class ApplicationClient {
|
|||||||
testInterServiceValidation(client);
|
testInterServiceValidation(client);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("error: " + e.getMessage());
|
IO.println("error: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testVehicles(CloseableHttpClient client) throws Exception {
|
private static void testVehicles(CloseableHttpClient client) {
|
||||||
System.out.println("--- VEHICLES ---");
|
IO.println("--- VEHICLES ---");
|
||||||
|
|
||||||
execute(client, new HttpGet(VEHICLES_BASE_URL + "/vehicles"), "GET all vehicles");
|
execute(client, new HttpGet(BASE_URL + "/vehicle-service/vehicles"), "GET all vehicles");
|
||||||
|
|
||||||
var newVehicle = new VehicleRequest("Mercedes", "Actros", "AA1234BB", 2023, 18000, Vehicle.Status.AVAILABLE);
|
Vehicle newVehicle = new Vehicle(0, "Mercedes", "Actros", "AA1234BB", 2023, 18000, Vehicle.Status.AVAILABLE);
|
||||||
String vehicleXml = xmlMapper.writeValueAsString(newVehicle);
|
String vehicleXml = xmlMapper.writeValueAsString(newVehicle);
|
||||||
HttpPost post = new HttpPost(VEHICLES_BASE_URL + "/vehicles");
|
HttpPost post = new HttpPost(BASE_URL + "/vehicle-service/vehicles");
|
||||||
post.setEntity(new StringEntity(vehicleXml, "UTF-8"));
|
post.setEntity(new StringEntity(vehicleXml, "UTF-8"));
|
||||||
post.setHeader("Content-Type", "application/xml");
|
post.setHeader("Content-Type", "application/xml");
|
||||||
post.setHeader("Accept", "application/xml");
|
post.setHeader("Accept", "application/xml");
|
||||||
String createdVehicle = execute(client, post, "POST new vehicle");
|
String createdVehicle = execute(client, post, "POST new vehicle");
|
||||||
|
|
||||||
var get = new HttpGet(VEHICLES_BASE_URL + "/vehicles/1");
|
var get = new HttpGet(BASE_URL + "/vehicle-service/vehicles/1");
|
||||||
get.setHeader("Content-Type", "application/xml");
|
get.setHeader("Content-Type", "application/xml");
|
||||||
execute(client, get, "GET vehicle by ID=1");
|
execute(client, get, "GET vehicle by ID=1");
|
||||||
execute(client, new HttpGet(VEHICLES_BASE_URL + "/vehicles/999"), "GET vehicle by ID=999 (not found)");
|
execute(client, new HttpGet(BASE_URL + "/vehicle-service/vehicles/999"), "GET vehicle by ID=999 (not found)");
|
||||||
|
|
||||||
var updateVehicle = new VehicleRequest("Volvo", "FH16", "BB5678CC", 2024, 20000, Vehicle.Status.MAINTENANCE);
|
Vehicle updateVehicle = new Vehicle(1, "Volvo", "FH16", "BB5678CC", 2024, 20000, Vehicle.Status.MAINTENANCE);
|
||||||
var vehiclePut = createHttpRequest(updateVehicle, "/vehicles/1", HttpMethod.PUT);
|
var vehiclePut = createHttpRequest(updateVehicle, "/vehicle-service/vehicles/1", HttpMethod.PUT);
|
||||||
execute(client, vehiclePut, "PUT update vehicle ID=1");
|
execute(client, vehiclePut, "PUT update vehicle ID=1");
|
||||||
|
|
||||||
var patchVehicle = new VehicleRequest("Volvo", "FH16", "BB5678CC", 2024, 20000, Vehicle.Status.IN_TRANSIT);
|
Vehicle patchVehicle = new Vehicle(1, "Volvo", "FH16", "BB5678CC", 2024, 20000, Vehicle.Status.IN_TRANSIT);
|
||||||
var vehiclePatch = createHttpRequest(patchVehicle, "/vehicles/1", HttpMethod.PATCH);
|
var vehiclePatch = createHttpRequest(patchVehicle, "/vehicle-service/vehicles/1", HttpMethod.PATCH);
|
||||||
execute(client, vehiclePatch, "PATCH update vehicle ID=1");
|
execute(client, vehiclePatch, "PATCH update vehicle ID=1");
|
||||||
|
|
||||||
execute(client, new HttpDelete(VEHICLES_BASE_URL + "/vehicles/999"), "DELETE vehicle ID=999 (not found)");
|
execute(client, new HttpDelete(BASE_URL + "/vehicle-service/vehicles/999"), "DELETE vehicle ID=999 (not found)");
|
||||||
|
|
||||||
System.out.println();
|
IO.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testFreights(CloseableHttpClient client) throws Exception {
|
private static void testFreights(CloseableHttpClient client) {
|
||||||
System.out.println("--- FREIGHTS ---");
|
IO.println("--- FREIGHTS ---");
|
||||||
|
|
||||||
execute(client, new HttpGet(FREIGHTS_BASE_URL + "/freights"), "GET all freights");
|
execute(client, new HttpGet(BASE_URL + "/freight-service" + "/freights"), "GET all freights");
|
||||||
|
|
||||||
var dims = new Freight.Dimensions(120, 100, 200);
|
Freight.Dimensions dims = new Freight.Dimensions(120, 100, 200);
|
||||||
var newFreight = new FreightRequest("Electronics", "Laptops and monitors", 500, dims, Freight.Status.PENDING);
|
Freight newFreight = new Freight(1, "Electronics", "Laptops and monitors", 500, dims, Freight.Status.PENDING);
|
||||||
var freightPost = createHttpRequest(newFreight, "/freights", HttpMethod.POST);
|
var freightPost = createHttpRequest(newFreight, "/freight-service/freights", HttpMethod.POST);
|
||||||
execute(client, freightPost, "POST new freight");
|
execute(client, freightPost, "POST new freight");
|
||||||
|
|
||||||
execute(client, new HttpGet(FREIGHTS_BASE_URL + "/freights/1"), "GET freight by ID=1");
|
execute(client, new HttpGet(BASE_URL + "/freight-service/freights/1"), "GET freight by ID=1");
|
||||||
execute(client, new HttpGet(FREIGHTS_BASE_URL + "/freights/999"), "GET freight by ID=999 (not found)");
|
execute(client, new HttpGet(BASE_URL + "/freight-service/freights/999"), "GET freight by ID=999 (not found)");
|
||||||
|
|
||||||
var updateFreight = new FreightRequest("Furniture", "Office desks", 800, dims, Freight.Status.IN_TRANSIT);
|
Freight updateFreight = new Freight(1, "Furniture", "Office desks", 800, dims, Freight.Status.IN_TRANSIT);
|
||||||
var freightPut = createHttpRequest(updateFreight, "/freights/1", HttpMethod.PUT);
|
var freightPut = createHttpRequest(updateFreight, "/freight-service/freights/1", HttpMethod.PUT);
|
||||||
execute(client, freightPut, "PUT update freight ID=1");
|
execute(client, freightPut, "PUT update freight ID=1");
|
||||||
|
|
||||||
var patchFreight = new FreightRequest("Furniture", "Office desks", 800, dims, Freight.Status.DELIVERED);
|
Freight patchFreight = new Freight(1, "Furniture", "Office desks", 800, dims, Freight.Status.DELIVERED);
|
||||||
var freightPatch = createHttpRequest(patchFreight, "/freights/1", HttpMethod.PATCH);
|
var freightPatch = createHttpRequest(patchFreight, "/freight-service/freights/1", HttpMethod.PATCH);
|
||||||
execute(client, freightPatch, "PATCH update freight ID=1");
|
execute(client, freightPatch, "PATCH update freight ID=1");
|
||||||
|
|
||||||
execute(client, new HttpDelete(FREIGHTS_BASE_URL + "/freights/999"), "DELETE freight ID=999 (not found)");
|
execute(client, new HttpDelete(BASE_URL + "/freight-service/freights/999"), "DELETE freight ID=999 (not found)");
|
||||||
|
|
||||||
System.out.println();
|
IO.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testRoutes(CloseableHttpClient client) throws Exception {
|
private static void testRoutes(CloseableHttpClient client) {
|
||||||
System.out.println("--- ROUTES ---");
|
IO.println("--- ROUTES ---");
|
||||||
|
|
||||||
var newRoute = new RouteRequest(1, List.of(1L), "Kyiv", "Lviv", 540.0, 8.5, Route.Status.PLANNED);
|
Route newRoute = new Route(1, 1, List.of(1L), "Kyiv", "Lviv", 540.0, 8.5, Route.Status.PLANNED);
|
||||||
var routePost = createHttpRequest(newRoute, "/routes", HttpMethod.POST);
|
var routePost = createHttpRequest(newRoute, "/route-service/routes", HttpMethod.POST);
|
||||||
execute(client, routePost, "POST new route");
|
execute(client, routePost, "POST new route");
|
||||||
|
|
||||||
execute(client, new HttpGet(ROUTES_BASE_URL + "/routes"), "GET all routes");
|
execute(client, new HttpGet(BASE_URL + "/route-service" + "/routes"), "GET all routes");
|
||||||
|
|
||||||
execute(client, new HttpGet(ROUTES_BASE_URL + "/routes/1"), "GET route by ID=1");
|
execute(client, new HttpGet(BASE_URL + "/route-service" + "/routes/1"), "GET route by ID=1");
|
||||||
execute(client, new HttpGet(ROUTES_BASE_URL + "/routes/999"), "GET route by ID=999 (not found)");
|
execute(client, new HttpGet(BASE_URL + "/route-service" + "/routes/999"), "GET route by ID=999 (not found)");
|
||||||
|
|
||||||
var updateRoute = new RouteRequest(1, List.of(1L), "Kyiv", "Odesa", 480.0, 7.0, Route.Status.IN_PROGRESS);
|
Route updateRoute = new Route(1, 1, List.of(1L), "Kyiv", "Odesa", 480.0, 7.0, Route.Status.IN_PROGRESS);
|
||||||
var routePut = createHttpRequest(updateRoute, "/routes/1", HttpMethod.PUT);
|
var routePut = createHttpRequest(updateRoute, "/route-service/routes/1", HttpMethod.PUT);
|
||||||
execute(client, routePut, "PUT update route ID=1");
|
execute(client, routePut, "PUT update route ID=1");
|
||||||
|
|
||||||
var patchRoute = new RouteRequest(1, List.of(1L), "Kyiv", "Odesa", 480.0, 7.0, Route.Status.COMPLETED);
|
Route patchRoute = new Route(1, 1, List.of(1L), "Kyiv", "Odesa", 480.0, 7.0, Route.Status.COMPLETED);
|
||||||
var routePatch = createHttpRequest(patchRoute, "/routes/1", HttpMethod.PATCH);
|
var routePatch = createHttpRequest(patchRoute, "/route-service/routes/1", HttpMethod.PATCH);
|
||||||
execute(client, routePatch, "PATCH update route ID=1");
|
execute(client, routePatch, "PATCH update route ID=1");
|
||||||
|
|
||||||
execute(client, new HttpDelete(ROUTES_BASE_URL + "/routes/999"), "DELETE route ID=999 (not found)");
|
execute(client, new HttpDelete(BASE_URL + "/route-service" + "/routes/999"), "DELETE route ID=999 (not found)");
|
||||||
|
|
||||||
System.out.println();
|
IO.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testSubResources(CloseableHttpClient client) throws Exception {
|
private static void testSubResources(CloseableHttpClient client) {
|
||||||
System.out.println("--- SUB-RESOURCES ---");
|
IO.println("--- SUB-RESOURCES ---");
|
||||||
|
|
||||||
execute(client, new HttpGet(ROUTES_BASE_URL + "/routes/1/freights"), "GET freights for route ID=1 (sub-resource)");
|
execute(client, new HttpGet(BASE_URL + "/route-service/routes/1/freights"), "GET freights for route ID=1 (sub-resource)");
|
||||||
execute(client, new HttpGet(ROUTES_BASE_URL + "/routes/1/vehicle"), "GET vehicle for route ID=1 (sub-resource)");
|
execute(client, new HttpGet(BASE_URL + "/route-service/routes/1/vehicle"), "GET vehicle for route ID=1 (sub-resource)");
|
||||||
|
|
||||||
System.out.println();
|
IO.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testStatusFiltering(CloseableHttpClient client) throws Exception {
|
private static void testStatusFiltering(CloseableHttpClient client) {
|
||||||
System.out.println("--- STATUS FILTERING ---");
|
IO.println("--- STATUS FILTERING ---");
|
||||||
|
|
||||||
execute(client, new HttpGet(VEHICLES_BASE_URL + "/vehicles?status=AVAILABLE"), "GET vehicles with status=AVAILABLE");
|
execute(client, new HttpGet(BASE_URL + "/vehicle-service/vehicles?status=AVAILABLE"), "GET vehicles with status=AVAILABLE");
|
||||||
execute(client, new HttpGet(VEHICLES_BASE_URL + "/vehicles?status=IN_TRANSIT"), "GET vehicles with status=IN_TRANSIT");
|
execute(client, new HttpGet(BASE_URL + "/vehicle-service/vehicles?status=IN_TRANSIT"), "GET vehicles with status=IN_TRANSIT");
|
||||||
execute(client, new HttpGet(FREIGHTS_BASE_URL + "/freights?status=PENDING"), "GET freights with status=PENDING");
|
execute(client, new HttpGet(BASE_URL + "/freight-service/freights?status=PENDING"), "GET freights with status=PENDING");
|
||||||
execute(client, new HttpGet(FREIGHTS_BASE_URL + "/freights?status=DELIVERED"), "GET freights with status=DELIVERED");
|
execute(client, new HttpGet(BASE_URL + "/freight-service/freights?status=DELIVERED"), "GET freights with status=DELIVERED");
|
||||||
execute(client, new HttpGet(ROUTES_BASE_URL + "/routes?status=PLANNED"), "GET routes with status=PLANNED");
|
execute(client, new HttpGet(BASE_URL + "/route-service/routes?status=PLANNED"), "GET routes with status=PLANNED");
|
||||||
execute(client, new HttpGet(ROUTES_BASE_URL + "/routes?status=COMPLETED"), "GET routes with status=COMPLETED");
|
execute(client, new HttpGet(BASE_URL + "/route-service/routes?status=COMPLETED"), "GET routes with status=COMPLETED");
|
||||||
|
|
||||||
System.out.println();
|
IO.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testErrorCases(CloseableHttpClient client) throws Exception {
|
private static void testErrorCases(CloseableHttpClient client) {
|
||||||
System.out.println("--- ERROR CASES (TESTING EXCEPTION HANDLING) ---");
|
IO.println("--- ERROR CASES (TESTING EXCEPTION HANDLING) ---");
|
||||||
|
|
||||||
execute(client, new HttpGet(VEHICLES_BASE_URL + "/vehicles/999"), "GET non-existent vehicle (404 Not Found)");
|
execute(client, new HttpGet(BASE_URL + "/vehicle-service/vehicles/999"), "GET non-existent vehicle (404 Not Found)");
|
||||||
execute(client, new HttpGet(FREIGHTS_BASE_URL + "/freights/-1"), "GET freight with invalid ID (404 Not Found)");
|
execute(client, new HttpGet(BASE_URL + "/freight-service/freights/-1"), "GET freight with invalid ID (404 Not Found)");
|
||||||
execute(client, new HttpGet(ROUTES_BASE_URL + "/routes/-1"), "GET route with invalid ID (404 Not Found)");
|
execute(client, new HttpGet(BASE_URL + "/route-service/routes/-1"), "GET route with invalid ID (404 Not Found)");
|
||||||
|
|
||||||
System.out.println();
|
IO.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testInterServiceValidation(CloseableHttpClient client) throws Exception {
|
private static void testInterServiceValidation(CloseableHttpClient client) {
|
||||||
System.out.println("--- INTER-SERVICE COMMUNICATION & VALIDATION ---");
|
IO.println("--- INTER-SERVICE COMMUNICATION & VALIDATION ---");
|
||||||
|
|
||||||
// Test 1: Create route with valid references (should succeed)
|
// Test 1: Create route with valid references (should succeed)
|
||||||
System.out.println("[INTER-SERVICE TEST 1] Creating route with valid vehicle and freight references:");
|
IO.println("[INTER-SERVICE TEST 1] Creating route with valid vehicle and freight references:");
|
||||||
var validRoute = new RouteRequest(1, List.of(1L), "Kyiv", "Lviv", 540.0, 8.5, Route.Status.PLANNED);
|
Route validRoute = new Route(1, 1, List.of(1L), "Kyiv", "Lviv", 540.0, 8.5, Route.Status.PLANNED);
|
||||||
var validRoutePost = createHttpRequest(validRoute, "/routes", HttpMethod.POST);
|
var validRoutePost = createHttpRequest(validRoute, "/route-service/routes", HttpMethod.POST);
|
||||||
execute(client, validRoutePost, "POST route with valid vehicle and freights (should succeed)");
|
execute(client, validRoutePost, "POST route with valid vehicle and freights (should succeed)");
|
||||||
|
|
||||||
// Test 2: Create route with invalid vehicle (should fail with 404)
|
// Test 2: Create route with invalid vehicle (should fail with 404)
|
||||||
System.out.println("[INTER-SERVICE TEST 2] Creating route with INVALID vehicle ID:");
|
IO.println("[INTER-SERVICE TEST 2] Creating route with INVALID vehicle ID:");
|
||||||
var invalidVehicleRoute = new RouteRequest(-999, List.of(1L), "Kyiv", "Lviv", 540.0, 8.5, Route.Status.PLANNED);
|
Route invalidVehicleRoute = new Route(1, -999, List.of(1L), "Kyiv", "Lviv", 540.0, 8.5, Route.Status.PLANNED);
|
||||||
var invalidRoutePost = createHttpRequest(invalidVehicleRoute, "/routes", HttpMethod.POST);
|
var invalidRoutePost = createHttpRequest(invalidVehicleRoute, "/route-service/routes", HttpMethod.POST);
|
||||||
execute(client, invalidRoutePost, "POST route with invalid vehicle ID, should result in 404");
|
execute(client, invalidRoutePost, "POST route with invalid vehicle ID, should result in 404");
|
||||||
|
|
||||||
// Test 3: Create route with invalid freight (should fail with 404)
|
// Test 3: Create route with invalid freight (should fail with 404)
|
||||||
System.out.println("[INTER-SERVICE TEST 3] Creating route with INVALID freight ID:");
|
IO.println("[INTER-SERVICE TEST 3] Creating route with INVALID freight ID:");
|
||||||
var invalidFreightRoute = new RouteRequest(1, List.of(-999L), "Kyiv", "Lviv", 540.0, 8.5, Route.Status.PLANNED);
|
Route invalidFreightRoute = new Route(1, 1, List.of(-999L), "Kyiv", "Lviv", 540.0, 8.5, Route.Status.PLANNED);
|
||||||
var invalidFreightPost = createHttpRequest(invalidFreightRoute, "/routes", HttpMethod.POST);
|
var invalidFreightPost = createHttpRequest(invalidFreightRoute, "/route-service/routes", HttpMethod.POST);
|
||||||
execute(client, invalidFreightPost, "POST route with invalid freight ID, should result in 404");
|
execute(client, invalidFreightPost, "POST route with invalid freight ID, should result in 404");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> HttpUriRequest createHttpRequest(T entity, String path, HttpMethod method) {
|
private static <T> HttpUriRequest createHttpRequest(T entity, String path, HttpMethod method) {
|
||||||
String entityJson = jsonMapper.writeValueAsString(entity);
|
String entityJson = jsonMapper.writeValueAsString(entity);
|
||||||
HttpEntityEnclosingRequestBase req;
|
HttpEntityEnclosingRequestBase req;
|
||||||
final String baseUrl = switch(entity) {
|
|
||||||
case FreightRequest _ -> FREIGHTS_BASE_URL;
|
|
||||||
case VehicleRequest _ -> VEHICLES_BASE_URL;
|
|
||||||
case RouteRequest _ -> ROUTES_BASE_URL;
|
|
||||||
default -> throw new IllegalArgumentException();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (method == HttpMethod.GET) {
|
if (method == HttpMethod.GET) {
|
||||||
return new HttpGet(baseUrl + path);
|
return new HttpGet(BASE_URL + path);
|
||||||
} else if (method == HttpMethod.POST) {
|
} else if (method == HttpMethod.POST) {
|
||||||
req = new HttpPost(baseUrl + path);
|
req = new HttpPost(BASE_URL + path);
|
||||||
req.setEntity(new StringEntity(entityJson, "UTF-8"));
|
req.setEntity(new StringEntity(entityJson, "UTF-8"));
|
||||||
req.setHeader("Content-Type", "application/json");
|
req.setHeader("Content-Type", "application/json");
|
||||||
return req;
|
return req;
|
||||||
} else if (method == HttpMethod.PUT) {
|
} else if (method == HttpMethod.PUT) {
|
||||||
req = new HttpPut(baseUrl + path);
|
req = new HttpPut(BASE_URL + path);
|
||||||
req.setEntity(new StringEntity(entityJson, "UTF-8"));
|
req.setEntity(new StringEntity(entityJson, "UTF-8"));
|
||||||
req.setHeader("Content-Type", "application/json");
|
req.setHeader("Content-Type", "application/json");
|
||||||
return req;
|
return req;
|
||||||
} else if (method == HttpMethod.PATCH) {
|
} else if (method == HttpMethod.PATCH) {
|
||||||
req = new HttpPatch(baseUrl + path);
|
req = new HttpPatch(BASE_URL + path);
|
||||||
req.setEntity(new StringEntity(entityJson, "UTF-8"));
|
req.setEntity(new StringEntity(entityJson, "UTF-8"));
|
||||||
req.setHeader("Content-Type", "application/json");
|
req.setHeader("Content-Type", "application/json");
|
||||||
return req;
|
return req;
|
||||||
} else if (method == HttpMethod.DELETE) {
|
} else if (method == HttpMethod.DELETE) {
|
||||||
return new HttpDelete(baseUrl + path);
|
return new HttpDelete(BASE_URL + path);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("method is invalid");
|
throw new IllegalArgumentException("method is invalid");
|
||||||
}
|
}
|
||||||
@@ -213,26 +202,26 @@ public class ApplicationClient {
|
|||||||
|
|
||||||
private static String execute(CloseableHttpClient client, HttpUriRequest request, String description) {
|
private static String execute(CloseableHttpClient client, HttpUriRequest request, String description) {
|
||||||
try {
|
try {
|
||||||
System.out.println("[" + request.getMethod() + "] " + description);
|
IO.println("[" + request.getMethod() + "] " + description);
|
||||||
CloseableHttpResponse response = client.execute(request);
|
CloseableHttpResponse response = client.execute(request);
|
||||||
int statusCode = response.getStatusLine().getStatusCode();
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
String body = response.getEntity() != null ? EntityUtils.toString(response.getEntity()) : "";
|
String body = response.getEntity() != null ? EntityUtils.toString(response.getEntity()) : "";
|
||||||
|
|
||||||
System.out.println("Status: " + statusCode);
|
IO.println("Status: " + statusCode);
|
||||||
if (!body.isEmpty()) {
|
if (!body.isEmpty()) {
|
||||||
System.out.println("Response: " + body);
|
IO.println("Response: " + body);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HttpStatus.valueOf(statusCode).isError()) {
|
if (HttpStatus.valueOf(statusCode).isError()) {
|
||||||
System.out.println("ERROR: Request failed with status " + statusCode);
|
IO.println("ERROR: Request failed with status " + statusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println();
|
IO.println();
|
||||||
return body;
|
return body;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("EXCEPTION: " + e.getMessage());
|
IO.println("EXCEPTION: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.out.println();
|
IO.println();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
// spring
|
// spring
|
||||||
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
|
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
|
||||||
|
implementation(platform(libs.spring.cloud.dependencies))
|
||||||
|
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-aop:4.0.0-M2")
|
||||||
implementation(libs.spring.boot.starter.web)
|
implementation(libs.spring.boot.starter.web)
|
||||||
implementation(libs.spring.boot.starter.web.test)
|
implementation(libs.spring.boot.starter.web.test)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package ua.com.dxrkness.aspect;
|
||||||
|
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class LoggingAspect {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
|
||||||
|
|
||||||
|
@Value("${server.port}")
|
||||||
|
private String port;
|
||||||
|
|
||||||
|
@Before("execution(* ua.com.dxrkness.controller.VehicleController.*(..))")
|
||||||
|
public void logBeforeMethod(JoinPoint joinPoint) {
|
||||||
|
String methodName = joinPoint.getSignature().getName();
|
||||||
|
logger.info(">>> [Instance Port: {}] - Calling method: {}", port, methodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,6 @@ import org.jspecify.annotations.NullMarked;
|
|||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import ua.com.dxrkness.dto.VehicleRequest;
|
|
||||||
import ua.com.dxrkness.model.Vehicle;
|
import ua.com.dxrkness.model.Vehicle;
|
||||||
import ua.com.dxrkness.service.VehicleService;
|
import ua.com.dxrkness.service.VehicleService;
|
||||||
|
|
||||||
@@ -69,8 +68,8 @@ public class VehicleController {
|
|||||||
description = "Vehicle object to be created",
|
description = "Vehicle object to be created",
|
||||||
required = true
|
required = true
|
||||||
)
|
)
|
||||||
@RequestBody VehicleRequest newVehicle) {
|
@RequestBody Vehicle newVehicle) {
|
||||||
return service.add(newVehicle.toEntity());
|
return service.add(newVehicle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
@@ -87,8 +86,8 @@ public class VehicleController {
|
|||||||
description = "Updated vehicle object",
|
description = "Updated vehicle object",
|
||||||
required = true
|
required = true
|
||||||
)
|
)
|
||||||
@RequestBody VehicleRequest newVehicle) {
|
@RequestBody Vehicle newVehicle) {
|
||||||
return service.update(id, newVehicle.toEntity());
|
return service.update(id, newVehicle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
@@ -105,8 +104,8 @@ public class VehicleController {
|
|||||||
description = "Vehicle object with fields to update",
|
description = "Vehicle object with fields to update",
|
||||||
required = true
|
required = true
|
||||||
)
|
)
|
||||||
@RequestBody VehicleRequest newVehicle) {
|
@RequestBody Vehicle newVehicle) {
|
||||||
return service.update(id, newVehicle.toEntity());
|
return service.update(id, newVehicle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,8 @@ spring:
|
|||||||
application:
|
application:
|
||||||
name: vehicle-service
|
name: vehicle-service
|
||||||
server:
|
server:
|
||||||
port: 8081
|
port: 8081
|
||||||
|
eureka:
|
||||||
|
client:
|
||||||
|
service-url:
|
||||||
|
defaultZone: http://localhost:8070/eureka
|
||||||
Reference in New Issue
Block a user