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
2 changes: 1 addition & 1 deletion core-quarkus-extensions/build-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<maven-enforcer-plugin.version>3.6.2</maven-enforcer-plugin.version>
<jacoco.plugin.version>0.8.7</jacoco.plugin.version>
<jandex-maven-plugin.version>3.5.3</jandex-maven-plugin.version>
<rest-libraries.version>6.4.1</rest-libraries.version>
<rest-libraries.version>6.4.2-SNAPSHOT</rest-libraries.version>
<maas-client.version>11.4.3</maas-client.version>
<error-handling.version>3.4.3</error-handling.version>
</properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jackson-deployment</artifactId>
</dependency>
<!-- Qubership -->
<dependency>
<groupId>com.netcracker.cloud.quarkus</groupId>
Expand Down
4 changes: 4 additions & 0 deletions core-quarkus-extensions/routes-registrator/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jackson</artifactId>
</dependency>
<!-- Qubership -->
<dependency>
<groupId>com.netcracker.cloud.quarkus</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.netcracker.cloud.quarkus.routesregistration.runtime.gateway.route;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.netcracker.cloud.quarkus.security.auth.M2MManager;
import com.netcracker.cloud.routesregistration.common.gateway.route.*;
import com.netcracker.cloud.routesregistration.common.gateway.route.rest.RegistrationRequestFactory;
import com.netcracker.cloud.routesregistration.common.gateway.route.transformation.RouteTransformer;
import com.netcracker.cloud.routesregistration.common.service.TopologyConfigService;
import com.netcracker.cloud.security.core.auth.Token;
import io.quarkus.arc.Unremovable;
import io.reactivex.Scheduler;
Expand All @@ -19,7 +21,7 @@

@ApplicationScoped
public class RouteRegistrationConfig {
private final static String DEFAULT_CONTROL_PLANE_ADDRESS = "http://control-plane:8080";

Check warning on line 24 in core-quarkus-extensions/routes-registrator/runtime/src/main/java/com/netcracker/cloud/quarkus/routesregistration/runtime/gateway/route/RouteRegistrationConfig.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Reorder the modifiers to comply with the Java Language Specification.

See more on https://sonarcloud.io/project/issues?id=Netcracker_qubership-core-java-libs&issues=AZ0FgeseuLbE7AhQnF4M&open=AZ0FgeseuLbE7AhQnF4M&pullRequest=4

public static final String CONTROL_PLANE_HTTP_CLIENT = "controlPlaneHttpClient";

Expand Down Expand Up @@ -104,7 +106,7 @@
@Produces
RoutesRegistrationDelayProvider routesRegistrationDelayProvider() {
RoutesRegistrationDelayProvider routesRegistrationDelayProvider = new RoutesRegistrationDelayProvider();
routesRegistrationDelayProvider.setProperties();

Check warning on line 109 in core-quarkus-extensions/routes-registrator/runtime/src/main/java/com/netcracker/cloud/quarkus/routesregistration/runtime/gateway/route/RouteRegistrationConfig.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this use of "setProperties"; it is deprecated.

See more on https://sonarcloud.io/project/issues?id=Netcracker_qubership-core-java-libs&issues=AZ0FgeseuLbE7AhQnF4N&open=AZ0FgeseuLbE7AhQnF4N&pullRequest=4
return routesRegistrationDelayProvider;
}

Expand All @@ -125,7 +127,9 @@
RoutesRestRegistrationProcessor routesRestRegistrationProcessor(ControlPlaneClient controlPlaneClient,
RouteRetryManager retryManager,
RouteTransformer routeTransformer,
RegistrationRequestFactory registrationRequestFactory) {
RegistrationRequestFactory registrationRequestFactory,
TopologyConfigService topologyConfigService) {

return new RoutesRestRegistrationProcessor(
controlPlaneClient,
retryManager,
Expand All @@ -138,6 +142,11 @@
);
}

@Produces
TopologyConfigService topologyConfigService(ObjectMapper objectMapper) {
return new TopologyConfigService(objectMapper);
}

private String getPort() {
return microservicePort;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package com.netcracker.cloud.routesregistration.common.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.netcracker.cloud.restclient.MicroserviceRestClient;
import io.reactivex.Scheduler;
import io.reactivex.schedulers.Schedulers;
import com.netcracker.cloud.routesregistration.common.annotation.processing.RouteHostMapping;
import com.netcracker.cloud.routesregistration.common.gateway.route.*;
import com.netcracker.cloud.routesregistration.common.gateway.route.rest.RegistrationRequestFactory;
import com.netcracker.cloud.routesregistration.common.gateway.route.transformation.RouteTransformer;
import com.netcracker.cloud.routesregistration.common.service.TopologyConfigService;
import com.netcracker.cloud.routesregistration.common.spring.gateway.route.RouteAnnotationProcessor;
import com.netcracker.cloud.routesregistration.common.spring.gateway.route.RouteFormatter;
import com.netcracker.cloud.routesregistration.common.spring.gateway.route.SpringControlPlaneClient;
import io.reactivex.Scheduler;
import io.reactivex.schedulers.Schedulers;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
Expand All @@ -20,6 +22,8 @@
import java.util.List;
import java.util.Optional;

import static com.netcracker.cloud.routesregistration.common.gateway.route.ServiceMeshType.ISTIO;

@Configuration
public class RouteRegistrationProcessorConfiguration {
private final String microserviceName;
Expand Down Expand Up @@ -47,7 +51,7 @@ public RouteRegistrationProcessorConfiguration(@Value("${cloud.microservice.name
this.postRoutesEnabled = postRoutesEnabled;

this.cloudServiceName = microserviceName;
if(deploymentVersion != null && !deploymentVersion.isEmpty()){
if (deploymentVersion != null && !deploymentVersion.isEmpty()) {
this.cloudServiceName += "-" + deploymentVersion;
}
}
Expand Down Expand Up @@ -98,7 +102,9 @@ RouteTransformer routeTransformer() {
RoutesRestRegistrationProcessor routesRestRegistrationProcessor(ControlPlaneClient controlPlaneClient,
RouteRetryManager routeRetryManager,
RouteTransformer routeTransformer,
RegistrationRequestFactory registrationRequestFactory) {
RegistrationRequestFactory registrationRequestFactory,
TopologyConfigService topologyConfigService) {

String microserviceInternalURL = Utils.formatMicroserviceInternalURL(
cloudServiceName,
microserviceName,
Expand All @@ -111,7 +117,8 @@ RoutesRestRegistrationProcessor routesRestRegistrationProcessor(ControlPlaneClie
routeRetryManager,
routeTransformer,
registrationRequestFactory,
postRoutesEnabled,
postRoutesEnabled
&& topologyConfigService.getServiceMeshType() != ISTIO,
microserviceName,
microserviceInternalURL);
}
Expand All @@ -130,4 +137,9 @@ RouteFormatter routeFormatter() {
RoutesRegistrationDelayProvider routesRegistrationDelayProvider() {
return new RoutesRegistrationDelayProvider();
}

@Bean
TopologyConfigService topologyConfigService(ObjectMapper objectMapper) {
return new TopologyConfigService(objectMapper);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.20.2</version>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.netcracker.cloud.routesregistration.common.gateway.route;

public enum ServiceMeshType {
CORE,
ISTIO
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
import java.util.Collection;

@Slf4j
public class Utils {

Check warning on line 8 in core-rest-libraries/route-registration/route-registration-common/src/main/java/com/netcracker/cloud/routesregistration/common/gateway/route/Utils.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add a private constructor to hide the implicit public one.

See more on https://sonarcloud.io/project/issues?id=Netcracker_qubership-core-java-libs&issues=AZ0FgeuluLbE7AhQnF4O&open=AZ0FgeuluLbE7AhQnF4O&pullRequest=4
public static String formatMicroserviceInternalURL(String cloudServiceName,
String microserviceName,
String microservicePort,
String contextPath,
boolean postRoutesAppnameDisabled) {
String host = microserviceName;
if (cloudServiceName != null &&! cloudServiceName.isEmpty()) {
if (cloudServiceName != null && !cloudServiceName.isEmpty()) {
host = cloudServiceName;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.netcracker.cloud.routesregistration.common.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netcracker.cloud.routesregistration.common.gateway.route.ServiceMeshType;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Optional;

@Slf4j
public class TopologyConfigService {
private static final String TOPOLOGY_CONFIG_PATH_DEFAULT = "/etc/topology.json";
private static final String SERVICE_MESH_TYPE_PATH = "/featureFlags/core/serviceMeshType";

Check warning on line 18 in core-rest-libraries/route-registration/route-registration-common/src/main/java/com/netcracker/cloud/routesregistration/common/service/TopologyConfigService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor your code to get this URI from a customizable parameter.

See more on https://sonarcloud.io/project/issues?id=Netcracker_qubership-core-java-libs&issues=AZ0FgeuvuLbE7AhQnF4P&open=AZ0FgeuvuLbE7AhQnF4P&pullRequest=4

private final ObjectMapper objectMapper;
private final String topologyConfigPath;

private volatile ServiceMeshType serviceMeshType;

public TopologyConfigService(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
this.topologyConfigPath = Optional.ofNullable(System.getenv("TOPOLOGY_CONFIG_PATH"))
.filter(s -> !s.isBlank())
.orElse(TOPOLOGY_CONFIG_PATH_DEFAULT);
}

// visible for testing
TopologyConfigService(ObjectMapper objectMapper, String topologyConfigPath) {
this.objectMapper = objectMapper;
this.topologyConfigPath = topologyConfigPath;
}

public ServiceMeshType getServiceMeshType() {
if (serviceMeshType != null) {
return serviceMeshType;
}
synchronized (this) {
if (serviceMeshType != null) {
return serviceMeshType;
}
serviceMeshType = loadServiceMeshType();
}
return serviceMeshType;
}

private ServiceMeshType loadServiceMeshType() {
try (InputStream inputStream = Files.newInputStream(Paths.get(topologyConfigPath))) {
JsonNode root = objectMapper.readTree(inputStream);
JsonNode node = root.at(SERVICE_MESH_TYPE_PATH);

if (node.isMissingNode() || node.isNull()) {
log.warn("'{}' not found in topology config, defaulting to {}", SERVICE_MESH_TYPE_PATH, ServiceMeshType.CORE);
return ServiceMeshType.CORE;
}

return parseServiceMeshType(node.asText());

} catch (IOException e) {
log.warn("Failed to read topology config from '{}', defaulting to {}", topologyConfigPath, ServiceMeshType.CORE, e);
return ServiceMeshType.CORE;
}
}

private ServiceMeshType parseServiceMeshType(String value) {
return Arrays.stream(ServiceMeshType.values())
.filter(type -> type.name().equalsIgnoreCase(value))
.findFirst()
.orElseGet(() -> {
log.warn("Unknown serviceMeshType '{}', defaulting to {}", value, ServiceMeshType.CORE);
return ServiceMeshType.CORE;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.netcracker.cloud.routesregistration.common.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.netcracker.cloud.routesregistration.common.gateway.route.ServiceMeshType;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import static org.junit.jupiter.api.Assertions.*;

class TopologyConfigServiceTest {

private static final ObjectMapper objectMapper = new ObjectMapper();

private TopologyConfigService service(String content) throws IOException {
Path file = Files.createTempFile("topology", ".json");
Files.writeString(file, content);
file.toFile().deleteOnExit();
return new TopologyConfigService(objectMapper, file.toString());
}

private TopologyConfigService serviceWithPath(String path) {
return new TopologyConfigService(objectMapper, path);
}

@Test
void defaultsToCoreWhenFileNotFound() {
TopologyConfigService service = serviceWithPath("/nonexistent/topology.json");
assertEquals(ServiceMeshType.CORE, service.getServiceMeshType());
}

@Test
void defaultsToCoreWhenFileIsMalformed() throws IOException {
TopologyConfigService service = service("not valid json");
assertEquals(ServiceMeshType.CORE, service.getServiceMeshType());
}

@Test
void defaultsToCoreWhenNodeIsMissing() throws IOException {
TopologyConfigService service = service("{}");
assertEquals(ServiceMeshType.CORE, service.getServiceMeshType());
}

@Test
void defaultsToCoreWhenServiceMeshTypeIsNull() throws IOException {

Check warning on line 47 in core-rest-libraries/route-registration/route-registration-common/src/test/java/com/netcracker/cloud/routesregistration/common/service/TopologyConfigServiceTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace these 3 tests with a single Parameterized one.

See more on https://sonarcloud.io/project/issues?id=Netcracker_qubership-core-java-libs&issues=AZ0FgevuuLbE7AhQnF4Q&open=AZ0FgevuuLbE7AhQnF4Q&pullRequest=4
TopologyConfigService service = service("""
{"featureFlags":{"core":{"serviceMeshType":null}}}
""");
assertEquals(ServiceMeshType.CORE, service.getServiceMeshType());
}

@Test
void defaultsToCoreWhenServiceMeshTypeIsUnknown() throws IOException {
TopologyConfigService service = service("""
{"featureFlags":{"core":{"serviceMeshType":"UNKNOWN"}}}
""");
assertEquals(ServiceMeshType.CORE, service.getServiceMeshType());
}

@Test
void returnsCoreWhenServiceMeshTypeIsCore() throws IOException {
TopologyConfigService service = service("""
{"featureFlags":{"core":{"serviceMeshType":"CORE"}}}
""");
assertEquals(ServiceMeshType.CORE, service.getServiceMeshType());
}

@Test
void returnsIstioWhenServiceMeshTypeIsIstio() throws IOException {
TopologyConfigService service = service("""
{"featureFlags":{"core":{"serviceMeshType":"ISTIO"}}}
""");
assertEquals(ServiceMeshType.ISTIO, service.getServiceMeshType());
}

@Test
void isCaseInsensitive() throws IOException {
TopologyConfigService service = service("""
{"featureFlags":{"core":{"serviceMeshType":"istio"}}}
""");
assertEquals(ServiceMeshType.ISTIO, service.getServiceMeshType());
}

@Test
void cachesResultOnSubsequentCalls() throws IOException {
TopologyConfigService service = service("""
{"featureFlags":{"core":{"serviceMeshType":"ISTIO"}}}
""");
assertEquals(ServiceMeshType.ISTIO, service.getServiceMeshType());
assertEquals(ServiceMeshType.ISTIO, service.getServiceMeshType());
}
}
Loading