diff --git a/core-microservice-framework/microservice-framework-resttemplate/src/test/java/com/netcracker/cloud/microserviceframework/application/BaseApplicationOnRestTemplateTest.java b/core-microservice-framework/microservice-framework-resttemplate/src/test/java/com/netcracker/cloud/microserviceframework/application/BaseApplicationOnRestTemplateTest.java
index ce9a4c467..a45ddd748 100644
--- a/core-microservice-framework/microservice-framework-resttemplate/src/test/java/com/netcracker/cloud/microserviceframework/application/BaseApplicationOnRestTemplateTest.java
+++ b/core-microservice-framework/microservice-framework-resttemplate/src/test/java/com/netcracker/cloud/microserviceframework/application/BaseApplicationOnRestTemplateTest.java
@@ -1,6 +1,7 @@
package com.netcracker.cloud.microserviceframework.application;
import com.netcracker.cloud.dbaas.client.DbaasClient;
+import com.netcracker.cloud.restclient.MicroserviceRestClient;
import com.netcracker.cloud.restclient.resttemplate.MicroserviceRestTemplate;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -23,7 +24,7 @@ class BaseApplicationOnRestTemplateTest {
@Test
void testDbaasRestClientInitialized() {
assertThat("Bean 'dbaasRestClient' is missing in context",
- context.getBean("dbaasRestClient") instanceof MicroserviceRestTemplate);
+ context.getBean("dbaasRestClient") instanceof MicroserviceRestClient);
}
@Test
diff --git a/core-microservice-framework/microservice-framework-resttemplate/src/test/java/com/netcracker/cloud/microserviceframework/application/TestApplicationOnRestTemplate.java b/core-microservice-framework/microservice-framework-resttemplate/src/test/java/com/netcracker/cloud/microserviceframework/application/TestApplicationOnRestTemplate.java
index 501c933e9..8fc33588f 100644
--- a/core-microservice-framework/microservice-framework-resttemplate/src/test/java/com/netcracker/cloud/microserviceframework/application/TestApplicationOnRestTemplate.java
+++ b/core-microservice-framework/microservice-framework-resttemplate/src/test/java/com/netcracker/cloud/microserviceframework/application/TestApplicationOnRestTemplate.java
@@ -7,8 +7,12 @@
import org.springframework.cloud.config.client.ConfigClientAutoConfiguration;
import org.springframework.context.annotation.Configuration;
+import com.netcracker.cloud.security.common.DummyM2MManagerConfiguration;
+import org.springframework.context.annotation.Import;
+
@Configuration
@EnableServiceDbaasPostgresql
@EnableAutoConfiguration(exclude = {DataElasticsearchAutoConfiguration.class, ConfigClientAutoConfiguration.class})
+@Import(DummyM2MManagerConfiguration.class)
public class TestApplicationOnRestTemplate extends BaseApplicationOnRestTemplate {
}
diff --git a/core-microservice-framework/microservice-framework-webclient/src/test/java/com/netcracker/cloud/microserviceframework/application/BaseApplicationOnWebClientTest.java b/core-microservice-framework/microservice-framework-webclient/src/test/java/com/netcracker/cloud/microserviceframework/application/BaseApplicationOnWebClientTest.java
index a7157f9f2..8047826f8 100644
--- a/core-microservice-framework/microservice-framework-webclient/src/test/java/com/netcracker/cloud/microserviceframework/application/BaseApplicationOnWebClientTest.java
+++ b/core-microservice-framework/microservice-framework-webclient/src/test/java/com/netcracker/cloud/microserviceframework/application/BaseApplicationOnWebClientTest.java
@@ -1,6 +1,7 @@
package com.netcracker.cloud.microserviceframework.application;
import com.netcracker.cloud.dbaas.client.DbaasClient;
+import com.netcracker.cloud.restclient.MicroserviceRestClient;
import com.netcracker.cloud.restclient.webclient.MicroserviceWebClient;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -23,7 +24,7 @@ class BaseApplicationOnWebClientTest {
@Test
void testDbaasRestClientInitialized() {
assertThat("Bean 'dbaasRestClient' is missing in context",
- context.getBean("dbaasRestClient") instanceof MicroserviceWebClient);
+ context.getBean("dbaasRestClient") instanceof MicroserviceRestClient);
}
@Test
diff --git a/core-microservice-framework/microservice-framework-webclient/src/test/java/com/netcracker/cloud/microserviceframework/application/TestApplicationOnWebClient.java b/core-microservice-framework/microservice-framework-webclient/src/test/java/com/netcracker/cloud/microserviceframework/application/TestApplicationOnWebClient.java
index 853f40607..2a6e81e58 100644
--- a/core-microservice-framework/microservice-framework-webclient/src/test/java/com/netcracker/cloud/microserviceframework/application/TestApplicationOnWebClient.java
+++ b/core-microservice-framework/microservice-framework-webclient/src/test/java/com/netcracker/cloud/microserviceframework/application/TestApplicationOnWebClient.java
@@ -2,13 +2,16 @@
import com.netcracker.cloud.dbaas.client.config.EnableServiceDbaasPostgresql;
import com.netcracker.cloud.microserviceframework.BaseApplicationOnWebClient;
+import com.netcracker.cloud.security.common.DummyM2MManagerConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.data.elasticsearch.autoconfigure.DataElasticsearchAutoConfiguration;
import org.springframework.cloud.config.client.ConfigClientAutoConfiguration;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
@Configuration
@EnableServiceDbaasPostgresql
@EnableAutoConfiguration(exclude = {DataElasticsearchAutoConfiguration.class, ConfigClientAutoConfiguration.class})
+@Import(DummyM2MManagerConfiguration.class)
public class TestApplicationOnWebClient extends BaseApplicationOnWebClient {
}
diff --git a/core-quarkus-extensions/config-sources/springcloud-config-source/runtime/pom.xml b/core-quarkus-extensions/config-sources/springcloud-config-source/runtime/pom.xml
index db01951f3..9c8dabcea 100644
--- a/core-quarkus-extensions/config-sources/springcloud-config-source/runtime/pom.xml
+++ b/core-quarkus-extensions/config-sources/springcloud-config-source/runtime/pom.xml
@@ -58,7 +58,13 @@
com.squareup.okhttp3
okhttp
-
+
+ com.netcracker.cloud.security.core.utils
+ k8s-utils
+ 3.1.0-SNAPSHOT
+
+
+
org.mockito
mockito-core
diff --git a/core-quarkus-extensions/config-sources/springcloud-config-source/runtime/src/main/java/com/netcracker/cloud/springcloud/config/source/ConfigServerClientImpl.java b/core-quarkus-extensions/config-sources/springcloud-config-source/runtime/src/main/java/com/netcracker/cloud/springcloud/config/source/ConfigServerClientImpl.java
index 55802062b..e3c260562 100644
--- a/core-quarkus-extensions/config-sources/springcloud-config-source/runtime/src/main/java/com/netcracker/cloud/springcloud/config/source/ConfigServerClientImpl.java
+++ b/core-quarkus-extensions/config-sources/springcloud-config-source/runtime/src/main/java/com/netcracker/cloud/springcloud/config/source/ConfigServerClientImpl.java
@@ -6,8 +6,8 @@
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import com.netcracker.cloud.quarkus.security.auth.M2MManager;
-import com.netcracker.cloud.security.core.auth.Token;
import com.netcracker.cloud.security.core.utils.tls.TlsUtils;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import okhttp3.*;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.eclipse.microprofile.config.Config;
@@ -36,7 +36,8 @@ public class ConfigServerClientImpl implements ConfigServerClient {
private URL url;
public ConfigServerClientImpl(String csUrl) throws MalformedURLException {
- client = new OkHttpClient.Builder()
+ client = M2MClientFactory.getM2mOkHttpClient(() -> M2MManager.getInstance().getToken().getTokenValue())
+ .newBuilder()
.connectionSpecs(Collections.singletonList(
csUrl.startsWith("https") ? ConnectionSpec.COMPATIBLE_TLS : ConnectionSpec.CLEARTEXT)
)
@@ -87,9 +88,7 @@ private String processRequest(Request request) throws IOException {
int count = 1;
while (true) {
try {
- Token token = M2MManager.getInstance().getToken();
request = request.newBuilder()
- .addHeader("Authorization", token.getTokenType() + " " + token.getTokenValue())
.build();
Response response = client.newCall(request).execute();
return response.body().string();
diff --git a/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/pom.xml b/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/pom.xml
index 7fd6ee6d2..b512de634 100644
--- a/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/pom.xml
+++ b/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/pom.xml
@@ -63,6 +63,11 @@
com.netcracker.cloud.security.core.utils
tls-utils
+
+ com.netcracker.cloud.security.core.utils
+ k8s-utils
+ 3.1.0-SNAPSHOT
+
io.quarkus
diff --git a/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/DbaasClientProducer.java b/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/DbaasClientProducer.java
index efc805b3c..1d5da1be2 100644
--- a/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/DbaasClientProducer.java
+++ b/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/DbaasClientProducer.java
@@ -12,14 +12,14 @@ public class DbaasClientProducer {
@Produces
@DefaultBean
- public DbaasClient dbaaSClient(DbaasClientConfig dbaasClientConfig) {
+ public DbaasClient dbaaSClient(SecurityConfig securityConfig, DbaasClientConfig dbaasClientConfig) {
if (dbaasClientConfig.dbaasUrl().isPresent() && dbaasClientConfig.dbaasUsername().isPresent() && dbaasClientConfig.dbaasPassword().isPresent()) {
log.debug("Create dbaas client with basic auth");
return new BasicDbaaSClient(dbaasClientConfig).build();
}
log.debug("Create dbaas client with m2m auth");
- return new M2MDbaaSClient(dbaasClientConfig).build();
+ return new M2MDbaaSClient(securityConfig, dbaasClientConfig).build();
}
}
diff --git a/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/M2MDbaaSClient.java b/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/M2MDbaaSClient.java
index 559aa3ddc..8681e0213 100644
--- a/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/M2MDbaaSClient.java
+++ b/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/M2MDbaaSClient.java
@@ -1,40 +1,53 @@
package com.netcracker.cloud.dbaas.common.config;
-import jakarta.enterprise.context.ApplicationScoped;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
import com.netcracker.cloud.context.propagation.core.ContextManager;
import com.netcracker.cloud.dbaas.client.DbaaSClientOkHttpImpl;
import com.netcracker.cloud.dbaas.client.DbaasClient;
import com.netcracker.cloud.framework.contexts.tenant.TenantContextObject;
import com.netcracker.cloud.quarkus.security.auth.M2MManager;
-import com.netcracker.cloud.security.core.auth.Token;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import com.netcracker.cloud.security.core.utils.tls.TlsUtils;
+import jakarta.enterprise.context.ApplicationScoped;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
import java.util.Optional;
import static com.netcracker.cloud.dbaas.common.config.DbaasClientConfig.DEFAULT_DBAAS_AGENT_ADDRESS;
import static com.netcracker.cloud.framework.contexts.tenant.BaseTenantProvider.TENANT_CONTEXT_NAME;
+@Slf4j
@ApplicationScoped
public class M2MDbaaSClient {
- private DbaasClientConfig config;
private static final int MAX_RETRIES = 3;
private static final long INITIAL_RETRY_DELAY = 500;
- public M2MDbaaSClient(DbaasClientConfig config) {
- this.config = config;
+ private final SecurityConfig securityConfig;
+ private final DbaasClientConfig dbaasConfig;
+
+ public M2MDbaaSClient(SecurityConfig securityConfig, DbaasClientConfig dbaasConfig) {
+ this.securityConfig = securityConfig;
+ this.dbaasConfig = dbaasConfig;
}
public DbaasClient build() {
- String url = config.dbaasAgentUrl().orElse(DEFAULT_DBAAS_AGENT_ADDRESS);
- OkHttpClient httpClient = new OkHttpClient.Builder()
+ String dbaasAgentUrl = dbaasConfig.dbaasAgentUrl().orElse(DEFAULT_DBAAS_AGENT_ADDRESS);
+
+ String dbaasUrl = dbaasAgentUrl;
+ if(securityConfig.k8sEnabled()) {
+ if(dbaasConfig.dbaasUrl().isEmpty()) {
+ log.warn("DBaaS address is not available, falling back to dbaas-agent. Specify 'api.dbaas.address' property to DBaaS url");
+ }
+ dbaasUrl = dbaasConfig.dbaasUrl().orElse(dbaasAgentUrl);
+ }
+
+ OkHttpClient httpClient = M2MClientFactory.getDbaasOkHttpClient(() -> M2MManager.getInstance().getToken().getTokenValue());
+
+ httpClient = httpClient.newBuilder()
.addInterceptor(chain -> {
Request original = chain.request();
- Token token = M2MManager.getInstance().getToken();
- String credentials = token.getTokenType() + " " + token.getTokenValue();
- Request.Builder requestBuilder = original.newBuilder()
- .addHeader("Authorization", credentials);
+ Request.Builder requestBuilder = original.newBuilder();
Optional tenantContextData = ContextManager.getSafe(TENANT_CONTEXT_NAME);
if (tenantContextData.isPresent() && tenantContextData.get().getTenant() != null) {
requestBuilder.addHeader("tenant", tenantContextData.get().getTenant());
@@ -44,6 +57,6 @@ public DbaasClient build() {
.addInterceptor(new RetryInterceptor(MAX_RETRIES, INITIAL_RETRY_DELAY))
.sslSocketFactory(TlsUtils.getSslContext().getSocketFactory(), TlsUtils.getTrustManager())
.build();
- return new DbaaSClientOkHttpImpl(url, httpClient);
+ return new DbaaSClientOkHttpImpl(dbaasUrl, httpClient);
}
}
diff --git a/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/SecurityConfig.java b/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/SecurityConfig.java
new file mode 100644
index 000000000..947f0bf49
--- /dev/null
+++ b/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/main/java/com/netcracker/cloud/dbaas/common/config/SecurityConfig.java
@@ -0,0 +1,15 @@
+package com.netcracker.cloud.dbaas.common.config;
+
+import io.smallrye.config.ConfigMapping;
+import io.smallrye.config.WithDefault;
+import io.smallrye.config.WithName;
+
+@ConfigMapping(prefix = "security.m2m")
+public interface SecurityConfig {
+ /**
+ * kubernetes tokens authentication enabled
+ */
+ @WithName("kubernetes.enabled")
+ @WithDefault("false")
+ boolean k8sEnabled();
+}
diff --git a/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/test/java/com/netcracker/cloud/dbaas/common/config/M2MDbaaSClientTest.java b/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/test/java/com/netcracker/cloud/dbaas/common/config/M2MDbaaSClientTest.java
index adea1a0b5..85c49a456 100644
--- a/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/test/java/com/netcracker/cloud/dbaas/common/config/M2MDbaaSClientTest.java
+++ b/core-quarkus-extensions/dbaas-client/dbaas-common/runtime/src/test/java/com/netcracker/cloud/dbaas/common/config/M2MDbaaSClientTest.java
@@ -16,11 +16,18 @@
class M2MDbaaSClientTest {
private M2MDbaaSClient m2MDbaaSClient;
private static final String DB_AGENT_URL = "http://dbaas-agent:8080";
+ private static final String DB_AGGREGATOR_URL = "http://dbaas-aggregator:8080";
+
@BeforeEach
void setUp() {
- DbaasClientConfig config = mock(DbaasClientConfig.class);
- when(config.dbaasAgentUrl()).thenReturn(Optional.of(DB_AGENT_URL));
- m2MDbaaSClient = new M2MDbaaSClient(config);
+ SecurityConfig securityConfig = mock(SecurityConfig.class);
+ when(securityConfig.k8sEnabled()).thenReturn(true);
+
+ DbaasClientConfig dbaasConfig = mock(DbaasClientConfig.class);
+ when(dbaasConfig.dbaasAgentUrl()).thenReturn(Optional.of(DB_AGENT_URL));
+ when(dbaasConfig.dbaasUrl()).thenReturn(Optional.of(DB_AGGREGATOR_URL));
+
+ m2MDbaaSClient = new M2MDbaaSClient(securityConfig, dbaasConfig);
}
@Test
void testBuild() throws NoSuchFieldException, IllegalAccessException {
@@ -29,8 +36,6 @@ void testBuild() throws NoSuchFieldException, IllegalAccessException {
clientField.setAccessible(true);
OkHttpClient clientValue = (OkHttpClient) clientField.get(client);
assertNotNull(client);
- assertEquals(2, clientValue.interceptors().size());
+ assertEquals(3, clientValue.interceptors().size());
}
}
-
-
diff --git a/core-quarkus-extensions/routes-registrator/runtime/pom.xml b/core-quarkus-extensions/routes-registrator/runtime/pom.xml
index cfc3433b1..19812eb3a 100644
--- a/core-quarkus-extensions/routes-registrator/runtime/pom.xml
+++ b/core-quarkus-extensions/routes-registrator/runtime/pom.xml
@@ -46,7 +46,12 @@
com.netcracker.cloud.security.core.utils
tls-utils
-
+
+ com.netcracker.cloud.security.core.utils
+ k8s-utils
+ 3.1.0-SNAPSHOT
+
+
io.quarkus
quarkus-junit
diff --git a/core-quarkus-extensions/routes-registrator/runtime/src/main/java/com/netcracker/cloud/quarkus/routesregistration/runtime/gateway/route/RouteRegistrationConfig.java b/core-quarkus-extensions/routes-registrator/runtime/src/main/java/com/netcracker/cloud/quarkus/routesregistration/runtime/gateway/route/RouteRegistrationConfig.java
index fca416dcb..c47acadbd 100644
--- a/core-quarkus-extensions/routes-registrator/runtime/src/main/java/com/netcracker/cloud/quarkus/routesregistration/runtime/gateway/route/RouteRegistrationConfig.java
+++ b/core-quarkus-extensions/routes-registrator/runtime/src/main/java/com/netcracker/cloud/quarkus/routesregistration/runtime/gateway/route/RouteRegistrationConfig.java
@@ -4,7 +4,7 @@
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.security.core.auth.Token;
+import com.netcracker.cloud.security.core.utils.tls.TlsUtils;
import io.quarkus.arc.Unremovable;
import io.reactivex.Scheduler;
import io.reactivex.schedulers.Schedulers;
@@ -12,8 +12,8 @@
import jakarta.enterprise.inject.Produces;
import jakarta.inject.Named;
import okhttp3.OkHttpClient;
-import okhttp3.Request;
import org.eclipse.microprofile.config.inject.ConfigProperty;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import java.util.Optional;
@@ -82,15 +82,8 @@ ControlPlaneClient controlPlaneClient(@Named(CONTROL_PLANE_HTTP_CLIENT) OkHttpCl
@Produces
@Named(CONTROL_PLANE_HTTP_CLIENT)
OkHttpClient controlPlaneHttpClient() {
- return new OkHttpClient.Builder()
- .addInterceptor(chain -> {
- Token token = M2MManager.getInstance().getToken();
- Request original = chain.request();
- Request request = original.newBuilder()
- .addHeader("Authorization", token.getTokenType() + " " + token.getTokenValue())
- .build();
- return chain.proceed(request);
- })
+ return M2MClientFactory.getM2mOkHttpClient(() -> M2MManager.getInstance().getToken().getTokenValue())
+ .newBuilder()
.retryOnConnectionFailure(true)
.build();
}
diff --git a/core-rest-libraries/config-server-loader/config-server-loader-resttemplate/pom.xml b/core-rest-libraries/config-server-loader/config-server-loader-resttemplate/pom.xml
index ff4748195..a9dd8a5b8 100644
--- a/core-rest-libraries/config-server-loader/config-server-loader-resttemplate/pom.xml
+++ b/core-rest-libraries/config-server-loader/config-server-loader-resttemplate/pom.xml
@@ -25,5 +25,15 @@
rest-security-adapters
${project.version}
+
+ com.netcracker.cloud
+ microservice-restclient-okhttp
+ 7.1.0-SNAPSHOT
+
+
+ com.netcracker.cloud.security.core.utils
+ k8s-utils
+ 3.1.0-SNAPSHOT
+
diff --git a/core-rest-libraries/config-server-loader/config-server-loader-resttemplate/src/main/java/com/netcracker/cloud/configserver/resttemplate/RestTemplateConfigServerConfigDataLocationResolver.java b/core-rest-libraries/config-server-loader/config-server-loader-resttemplate/src/main/java/com/netcracker/cloud/configserver/resttemplate/RestTemplateConfigServerConfigDataLocationResolver.java
index 23b3d2ca9..2bdf2c7c3 100644
--- a/core-rest-libraries/config-server-loader/config-server-loader-resttemplate/src/main/java/com/netcracker/cloud/configserver/resttemplate/RestTemplateConfigServerConfigDataLocationResolver.java
+++ b/core-rest-libraries/config-server-loader/config-server-loader-resttemplate/src/main/java/com/netcracker/cloud/configserver/resttemplate/RestTemplateConfigServerConfigDataLocationResolver.java
@@ -1,5 +1,7 @@
package com.netcracker.cloud.configserver.resttemplate;
+import com.netcracker.cloud.restclient.okhttp.MicroserviceOkHttpRestClient;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
@@ -14,10 +16,9 @@
import org.springframework.boot.bootstrap.ConfigurableBootstrapContext;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.client.JdkClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
-import java.util.Collections;
-
public class RestTemplateConfigServerConfigDataLocationResolver extends AbstractCustomConfigServerConfigDataLocationResolver {
@Value("${connection.readTimeout:60000}")
@@ -32,10 +33,14 @@ public RestTemplateConfigServerConfigDataLocationResolver(DeferredLogFactory log
@Override
public MicroserviceRestClient getMicroserviceRestClient() {
- return new MicroserviceRestTemplate(createM2MRestTemplate());
+ if (hasM2M(configurableBootstrapContext)) {
+ var client = M2MClientFactory.getM2mOkHttpClient(() -> getM2MToken(configurableBootstrapContext));
+ return new MicroserviceOkHttpRestClient(client);
+ }
+ return createM2MRestTemplate();
}
- private RestTemplate createM2MRestTemplate() {
+ private MicroserviceRestClient createM2MRestTemplate() {
RestTemplate template = new RestTemplate();
SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(Timeout.ofMilliseconds(readTimeout)).build();
@@ -45,14 +50,7 @@ private RestTemplate createM2MRestTemplate() {
HttpClient httpClient = HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager).build();
template.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
- if (hasM2M(configurableBootstrapContext)) {
- template.setInterceptors(Collections.singletonList((request, body, execution) -> {
- request.getHeaders().setBearerAuth(getM2MToken(configurableBootstrapContext));
- return execution.execute(request, body);
- }));
- }
-
- return template;
+ return new MicroserviceRestTemplate(template);
}
private String getM2MToken(ConfigurableBootstrapContext configurableBootstrapContext) {
diff --git a/core-rest-libraries/config-server-loader/config-server-loader-webclient/pom.xml b/core-rest-libraries/config-server-loader/config-server-loader-webclient/pom.xml
index 9a3efcdf6..efea56cb3 100644
--- a/core-rest-libraries/config-server-loader/config-server-loader-webclient/pom.xml
+++ b/core-rest-libraries/config-server-loader/config-server-loader-webclient/pom.xml
@@ -25,5 +25,15 @@
rest-security-adapters
${project.version}
+
+ com.netcracker.cloud
+ microservice-restclient-okhttp
+ 7.1.0-SNAPSHOT
+
+
+ com.netcracker.cloud.security.core.utils
+ k8s-utils
+ 3.1.0-SNAPSHOT
+
diff --git a/core-rest-libraries/config-server-loader/config-server-loader-webclient/src/main/java/com/netcracker/cloud/configserver/webclient/WebClientConfigServerConfigDataLocationResolver.java b/core-rest-libraries/config-server-loader/config-server-loader-webclient/src/main/java/com/netcracker/cloud/configserver/webclient/WebClientConfigServerConfigDataLocationResolver.java
index 9fa2e419b..dd7be08a5 100644
--- a/core-rest-libraries/config-server-loader/config-server-loader-webclient/src/main/java/com/netcracker/cloud/configserver/webclient/WebClientConfigServerConfigDataLocationResolver.java
+++ b/core-rest-libraries/config-server-loader/config-server-loader-webclient/src/main/java/com/netcracker/cloud/configserver/webclient/WebClientConfigServerConfigDataLocationResolver.java
@@ -2,14 +2,15 @@
import com.netcracker.cloud.configserver.common.configuration.AbstractCustomConfigServerConfigDataLocationResolver;
import com.netcracker.cloud.restclient.MicroserviceRestClient;
+import com.netcracker.cloud.restclient.okhttp.MicroserviceOkHttpRestClient;
import com.netcracker.cloud.restclient.webclient.MicroserviceWebClient;
import com.netcracker.cloud.security.core.auth.M2MManager;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import org.springframework.boot.bootstrap.ConfigurableBootstrapContext;
import org.springframework.boot.logging.DeferredLogFactory;
-import org.springframework.web.reactive.function.client.ClientRequest;
+import org.springframework.http.client.reactive.JdkClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;
-
-import static org.springframework.http.HttpHeaders.AUTHORIZATION;
+import java.net.http.HttpClient;
public class WebClientConfigServerConfigDataLocationResolver extends AbstractCustomConfigServerConfigDataLocationResolver {
@@ -22,19 +23,16 @@ public WebClientConfigServerConfigDataLocationResolver(DeferredLogFactory log, C
@Override
public MicroserviceRestClient getMicroserviceRestClient() {
- return new MicroserviceWebClient(createM2MWebClient());
- }
-
- private WebClient createM2MWebClient() {
- WebClient.Builder builder = WebClient.builder();
if (hasM2M(configurableBootstrapContext)) {
- builder.filter(
- (request, next) ->
- next.exchange(ClientRequest.from(request).
- header(AUTHORIZATION, "Bearer " + getM2MToken(configurableBootstrapContext)).build())
- );
+ var client = M2MClientFactory.getM2mOkHttpClient(() -> getM2MToken(configurableBootstrapContext));
+ return new MicroserviceOkHttpRestClient(client);
}
- return builder.build();
+ return createM2MWebClient();
+ }
+
+ private MicroserviceRestClient createM2MWebClient() {
+ var builder = WebClient.builder();
+ return new MicroserviceWebClient(builder.build());
}
private String getM2MToken(ConfigurableBootstrapContext configurableBootstrapContext) {
diff --git a/core-restclient/microservice-restclient-okhttp/pom.xml b/core-restclient/microservice-restclient-okhttp/pom.xml
new file mode 100644
index 000000000..95cd50f1d
--- /dev/null
+++ b/core-restclient/microservice-restclient-okhttp/pom.xml
@@ -0,0 +1,79 @@
+
+
+ 4.0.0
+
+ microservice-restclient-parent
+ com.netcracker.cloud
+ 7.1.0-SNAPSHOT
+ ../parent/pom.xml
+
+ microservice-restclient-okhttp
+
+
+ com.netcracker.cloud
+ microservice-restclient-api
+ ${project.version}
+
+
+ com.squareup.okhttp3
+ okhttp
+ 4.12.0
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.18.2
+ provided
+
+
+ org.projectlombok
+ lombok
+ 1.18.44
+ compile
+ true
+
+
+ org.slf4j
+ slf4j-api
+ 2.0.17
+ compile
+ true
+
+
+ org.slf4j
+ slf4j-simple
+ 2.0.17
+ test
+
+
+ com.netcracker.cloud
+ microservice-restclient-test-utils
+ ${project.version}
+ test
+
+
+ com.squareup.okhttp3
+ mockwebserver
+
+
+
+
+ com.squareup.okhttp3
+ mockwebserver
+ 4.12.0
+ test
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 6.0.3
+ test
+
+
+
diff --git a/core-restclient/microservice-restclient-okhttp/src/main/java/com/netcracker/cloud/restclient/okhttp/MicroserviceOkHttpRestClient.java b/core-restclient/microservice-restclient-okhttp/src/main/java/com/netcracker/cloud/restclient/okhttp/MicroserviceOkHttpRestClient.java
new file mode 100644
index 000000000..ec724d806
--- /dev/null
+++ b/core-restclient/microservice-restclient-okhttp/src/main/java/com/netcracker/cloud/restclient/okhttp/MicroserviceOkHttpRestClient.java
@@ -0,0 +1,150 @@
+package com.netcracker.cloud.restclient.okhttp;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.netcracker.cloud.core.error.rest.exception.RemoteCodeException;
+import com.netcracker.cloud.core.error.rest.tmf.DefaultTmfErrorResponseConverter;
+import com.netcracker.cloud.core.error.rest.tmf.TmfErrorResponse;
+import com.netcracker.cloud.core.error.rest.tmf.TmfErrorResponseConverter;
+import com.netcracker.cloud.restclient.AbstractMicroserviceRestClient;
+import com.netcracker.cloud.restclient.HttpMethod;
+import com.netcracker.cloud.restclient.entity.RestClientResponseEntity;
+import com.netcracker.cloud.restclient.exception.MicroserviceRestClientException;
+import com.netcracker.cloud.restclient.exception.MicroserviceRestClientResponseException;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+public class MicroserviceOkHttpRestClient extends AbstractMicroserviceRestClient {
+
+ private final OkHttpClient client;
+
+ @Getter
+ @Setter
+ private ObjectMapper mapper = new ObjectMapper()
+ .setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL)
+ .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+ @Getter
+ @Setter
+ private TmfErrorResponseConverter converter = new DefaultTmfErrorResponseConverter();
+
+ public MicroserviceOkHttpRestClient(OkHttpClient client) {
+ this.client = client;
+ }
+
+ @Override
+ public RestClientResponseEntity doRequest(String urlTemplate,
+ HttpMethod httpMethod,
+ Map> headers,
+ Object requestBody,
+ Class responseClass,
+ Map params) {
+ String expandedUrl = expandUrl(urlTemplate, params);
+ return doRequest(URI.create(expandedUrl), httpMethod, headers, requestBody, responseClass);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public RestClientResponseEntity doRequest(URI uri,
+ HttpMethod httpMethod,
+ Map> headers,
+ Object requestBody,
+ Class responseClass) {
+ Request.Builder requestBuilder = new Request.Builder().url(uri.toString());
+
+ Headers.Builder okHeadersBuilder = new Headers.Builder();
+ if (headers != null) {
+ headers.forEach((name, values) -> values.forEach(value -> okHeadersBuilder.add(name, value)));
+ }
+
+ if (okHeadersBuilder.get("Content-Type") == null) {
+ okHeadersBuilder.set("Content-Type", "application/json");
+ }
+ Headers okHeaders = okHeadersBuilder.build();
+ requestBuilder.headers(okHeaders);
+
+ RequestBody okBody = null;
+ if (requestBody != null) {
+ byte[] bodyBytes;
+ try {
+ if (requestBody instanceof String) {
+ bodyBytes = ((String) requestBody).getBytes();
+ } else if (requestBody instanceof byte[]) {
+ bodyBytes = (byte[]) requestBody;
+ } else {
+ bodyBytes = mapper.writeValueAsBytes(requestBody);
+ }
+ } catch (IOException e) {
+ throw new MicroserviceRestClientException("Failed to serialize request body", e);
+ }
+ okBody = RequestBody.create(bodyBytes, MediaType.parse(okHeaders.get("Content-Type")));
+ } else if (HttpMethod.POST.equals(httpMethod) || HttpMethod.PUT.equals(httpMethod) || HttpMethod.PATCH.equals(httpMethod)) {
+ okBody = RequestBody.create(new byte[0], MediaType.parse(okHeaders.get("Content-Type")));
+ }
+
+ requestBuilder.method(httpMethod.name(), okBody);
+
+ try (Response response = client.newCall(requestBuilder.build()).execute()) {
+ int code = response.code();
+ Map> responseHeaders = response.headers().toMultimap();
+ byte[] responseBodyBytes = null;
+ if (response.body() != null) {
+ responseBodyBytes = response.body().bytes();
+ }
+
+ if (response.isSuccessful()) {
+ T mappedBody = null;
+ if (responseBodyBytes != null && responseBodyBytes.length > 0 && responseClass != Void.class) {
+ if (responseClass == String.class) {
+ mappedBody = (T) new String(responseBodyBytes);
+ } else if (responseClass == byte[].class) {
+ mappedBody = (T) responseBodyBytes;
+ } else {
+ mappedBody = mapper.readValue(responseBodyBytes, responseClass);
+ }
+ }
+ return new RestClientResponseEntity<>(mappedBody, code, responseHeaders);
+ } else {
+ MicroserviceRestClientResponseException mce;
+ try {
+ if (responseBodyBytes != null && responseBodyBytes.length > 0) {
+ TmfErrorResponse tmfErrorResponse = mapper.readValue(responseBodyBytes, TmfErrorResponse.class);
+ final RemoteCodeException remoteCodeException = converter.buildErrorCodeException(tmfErrorResponse);
+ mce = new MicroserviceRestClientResponseException(remoteCodeException.getMessage(),
+ remoteCodeException, code, responseBodyBytes, responseHeaders);
+ } else {
+ mce = new MicroserviceRestClientResponseException("Request failed with status " + code,
+ null, code, responseBodyBytes, responseHeaders);
+ }
+ } catch (Exception ce) {
+ log.warn("Failed to parse response as TMF error response, cause: {}", ce.getMessage());
+ mce = new MicroserviceRestClientResponseException("Request failed with status " + code,
+ ce, code, responseBodyBytes, responseHeaders);
+ }
+ throw mce;
+ }
+ } catch (IOException e) {
+ throw new MicroserviceRestClientException(e.getMessage(), e);
+ }
+ }
+
+ private String expandUrl(String urlTemplate, Map params) {
+ if (params == null || params.isEmpty()) {
+ return urlTemplate;
+ }
+ String expanded = urlTemplate;
+ for (Map.Entry entry : params.entrySet()) {
+ expanded = expanded.replace("{" + entry.getKey() + "}", String.valueOf(entry.getValue()));
+ }
+ return expanded;
+ }
+}
diff --git a/core-restclient/microservice-restclient-okhttp/src/test/java/com/netcracker/cloud/restclient/okhttp/MicroserviceOkHttpRestClientTest.java b/core-restclient/microservice-restclient-okhttp/src/test/java/com/netcracker/cloud/restclient/okhttp/MicroserviceOkHttpRestClientTest.java
new file mode 100644
index 000000000..44898d871
--- /dev/null
+++ b/core-restclient/microservice-restclient-okhttp/src/test/java/com/netcracker/cloud/restclient/okhttp/MicroserviceOkHttpRestClientTest.java
@@ -0,0 +1,67 @@
+package com.netcracker.cloud.restclient.okhttp;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.netcracker.cloud.core.error.rest.exception.RemoteCodeException;
+import com.netcracker.cloud.core.error.rest.tmf.TmfErrorResponse;
+import com.netcracker.cloud.restclient.BaseMicroserviceRestClientTest;
+import com.netcracker.cloud.restclient.HttpMethod;
+import com.netcracker.cloud.restclient.exception.MicroserviceRestClientResponseException;
+import okhttp3.OkHttpClient;
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.RecordedRequest;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class MicroserviceOkHttpRestClientTest extends BaseMicroserviceRestClientTest {
+
+ @BeforeEach
+ void setUp() {
+ restClient = new MicroserviceOkHttpRestClient(new OkHttpClient());
+ }
+
+ @Test
+ void testDefaultRequestHeaders() throws InterruptedException {
+ mockBackEnd.enqueue(new MockResponse().setResponseCode(200).setBody("Test response body"));
+
+ restClient.doRequest(testUrl, HttpMethod.POST, null, null, Void.class);
+ RecordedRequest recordedRequest = mockBackEnd.takeRequest(60, TimeUnit.SECONDS);
+
+ assertNotNull(recordedRequest);
+ assertEquals("application/json", recordedRequest.getHeader("Content-Type"));
+ }
+
+ @Test
+ void testTMFRestClientResponseException() throws Exception {
+ TmfErrorResponse tmfErrorResponse = TmfErrorResponse.builder()
+ .id(UUID.randomUUID().toString())
+ .code("TEST")
+ .reason("test reason")
+ .detail("test detail")
+ .status("500")
+ .type(TmfErrorResponse.TYPE_V1_0)
+ .build();
+
+ mockBackEnd.enqueue(new MockResponse()
+ .setHeader("test-header", "test-value")
+ .setResponseCode(500)
+ .setBody(new ObjectMapper().writeValueAsString(tmfErrorResponse)));
+
+ try {
+ restClient.doRequest(testUrl, HttpMethod.POST, null, null, Void.class);
+ fail("Expected MicroserviceRestClientResponseException");
+ } catch (MicroserviceRestClientResponseException e) {
+ assertEquals(500, e.getHttpStatus());
+ assertEquals("test-value", e.getResponseHeaders().get("test-header").get(0));
+ assertTrue(e.getCause() instanceof RemoteCodeException);
+ RemoteCodeException remoteCodeException = (RemoteCodeException) e.getCause();
+ assertEquals(tmfErrorResponse.getCode(), remoteCodeException.getErrorCode().getCode());
+ } finally {
+ mockBackEnd.takeRequest(60, TimeUnit.SECONDS);
+ }
+ }
+}
diff --git a/core-restclient/parent/pom.xml b/core-restclient/parent/pom.xml
index 6366ef9b7..d70e42eab 100644
--- a/core-restclient/parent/pom.xml
+++ b/core-restclient/parent/pom.xml
@@ -27,6 +27,7 @@
${project.basedir}/../microservice-restclient-report-aggregate/target/site/jacoco-aggregate/jacoco.xml
+ 5.21.0
diff --git a/core-restclient/pom.xml b/core-restclient/pom.xml
index 351e12688..cb07852bc 100644
--- a/core-restclient/pom.xml
+++ b/core-restclient/pom.xml
@@ -22,6 +22,7 @@
microservice-restclient-test-utils
microservice-restclient-webclient
microservice-restclient-resttemplate
+ microservice-restclient-okhttp
microservice-restclient-report-aggregate
diff --git a/core-utils/k8s/pom.xml b/core-utils/k8s/pom.xml
index 79d62a963..ac34e350e 100644
--- a/core-utils/k8s/pom.xml
+++ b/core-utils/k8s/pom.xml
@@ -41,6 +41,16 @@
jose4j
0.9.6
+
+ com.github.ben-manes.caffeine
+ caffeine
+ 3.2.3
+
+
+ com.squareup.okhttp3
+ okhttp
+ 4.12.0
+
@@ -61,6 +71,7 @@
com.squareup.okhttp3
mockwebserver
+ 4.12.0
test
@@ -68,6 +79,18 @@
logback-classic
test
+
+ org.wiremock
+ wiremock
+ 3.13.2
+ test
+
+
+ com.github.stefanbirkner
+ system-lambda
+ 1.2.1
+ test
+
diff --git a/core-utils/k8s/src/main/java/com/netcracker/cloud/security/core/utils/k8s/M2MClientFactory.java b/core-utils/k8s/src/main/java/com/netcracker/cloud/security/core/utils/k8s/M2MClientFactory.java
new file mode 100644
index 000000000..dacb782e5
--- /dev/null
+++ b/core-utils/k8s/src/main/java/com/netcracker/cloud/security/core/utils/k8s/M2MClientFactory.java
@@ -0,0 +1,45 @@
+package com.netcracker.cloud.security.core.utils.k8s;
+
+import com.netcracker.cloud.security.core.utils.k8s.impl.M2MInterceptor;
+import com.netcracker.cloud.security.core.utils.k8s.impl.UrlCache;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import okhttp3.OkHttpClient;
+
+import java.util.Optional;
+import java.util.function.Supplier;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class M2MClientFactory {
+ public static final String DBAAS_AGENT_URL_PROP = "com.netcracker.cloud.dbaas.agent.url";
+ public static final String MAAS_AGENT_URL_PROP = "com.netcracker.cloud.maas.agent.url";
+
+ private static final Supplier k8sAuthHeaderSupplier =
+ getBearerAuthHeaderSupplier(() -> KubernetesAudienceToken.getToken(AudienceName.NETCRACKER));
+
+ public static OkHttpClient getM2mOkHttpClient(Supplier keycloakTokenSupplier) {
+ return getOkHttpClient(new M2MInterceptor(new UrlCache(), getBearerAuthHeaderSupplier(keycloakTokenSupplier), k8sAuthHeaderSupplier));
+ }
+
+ public static OkHttpClient getDbaasOkHttpClient(Supplier keycloakTokenSupplier) {
+ return getAgentOkHttpClient(keycloakTokenSupplier, Optional.ofNullable(System.getProperty(DBAAS_AGENT_URL_PROP)).orElse("http://dbaas-agent:8080"));
+ }
+
+ public static OkHttpClient getMaasOkHttpClient(Supplier keycloakTokenSupplier) {
+ return getAgentOkHttpClient(keycloakTokenSupplier, Optional.ofNullable(System.getProperty(MAAS_AGENT_URL_PROP)).orElse("http://maas-agent:8080"));
+ }
+
+ private static OkHttpClient getAgentOkHttpClient(Supplier keycloakTokenSupplier, String agentUrl) {
+ return getOkHttpClient(new M2MInterceptor(new UrlCache(), getBearerAuthHeaderSupplier(keycloakTokenSupplier), k8sAuthHeaderSupplier, agentUrl));
+ }
+
+ private static OkHttpClient getOkHttpClient(M2MInterceptor interceptor) {
+ return new OkHttpClient.Builder()
+ .addInterceptor(interceptor)
+ .build();
+ }
+
+ private static Supplier getBearerAuthHeaderSupplier(Supplier tokenSupplier) {
+ return () -> "Bearer " + tokenSupplier.get();
+ }
+}
diff --git a/core-utils/k8s/src/main/java/com/netcracker/cloud/security/core/utils/k8s/impl/M2MInterceptor.java b/core-utils/k8s/src/main/java/com/netcracker/cloud/security/core/utils/k8s/impl/M2MInterceptor.java
new file mode 100644
index 000000000..38b2acf16
--- /dev/null
+++ b/core-utils/k8s/src/main/java/com/netcracker/cloud/security/core/utils/k8s/impl/M2MInterceptor.java
@@ -0,0 +1,120 @@
+package com.netcracker.cloud.security.core.utils.k8s.impl;
+
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.HttpUrl;
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.function.Supplier;
+
+import static com.netcracker.cloud.security.core.utils.k8s.impl.UrlCache.calculateCacheKey;
+import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
+
+@Slf4j
+public final class M2MInterceptor implements Interceptor {
+
+ public static final String KUBERNETES_TOKEN_ACQUISITION_ERROR = """
+ Error acquiring kubernetes token for m2m communication.
+ The current version of the security library expects a kubernetes token with the `netcracker` audience to be mounted in the deployment.
+ if you do not intend to use a kubernetes token at this time, please roll back to a previous version of the library.
+ otherwise, make sure that a kubernetes token with the `netcracker` audience is properly mounted.
+ the previous authentication method will be used as a fallback.""";
+ public static final String KUBERNETES_TOKEN_UNAUTHORIZED_ERROR = """
+ Unauthorized access (http 401).
+ During an m2m interaction attempt using a kubernetes token with the `netcracker` audience, a 401 error was received.
+ The possible cause is an outdated version of the security library on the server side.
+ The previous authentication method will be used as a fallback.""";
+
+ private final boolean k8sEnabled;
+ private final UrlCache urlCache;
+ private final Supplier fallbackAuthHeaderSupplier;
+ private final Supplier k8sAuthHeaderSupplier;
+ private final HttpUrl fallbackBaseUrl;
+
+ public M2MInterceptor(UrlCache urlCache, Supplier fallbackAuthHeaderSupplier, Supplier k8sAuthHeaderSupplier) {
+ this(urlCache, fallbackAuthHeaderSupplier, k8sAuthHeaderSupplier, null);
+ }
+
+ public M2MInterceptor(UrlCache urlCache, Supplier fallbackAuthHeaderSupplier, Supplier k8sAuthHeaderSupplier, String fallbackBaseUrl) {
+ String k8sEnabledProp = System.getProperty("security.m2m.kubernetes.enabled");
+ if (k8sEnabledProp == null) {
+ k8sEnabledProp = System.getenv("SECURITY_M2M_KUBERNETES_ENABLED");
+ }
+
+ this.k8sEnabled = Boolean.parseBoolean(k8sEnabledProp);
+ this.urlCache = urlCache;
+ this.fallbackAuthHeaderSupplier = fallbackAuthHeaderSupplier;
+ this.k8sAuthHeaderSupplier = k8sAuthHeaderSupplier;
+ this.fallbackBaseUrl = (fallbackBaseUrl != null) ? HttpUrl.get(fallbackBaseUrl) : null;
+ }
+
+ @NotNull
+ @Override
+ public Response intercept(final Interceptor.Chain chain) throws IOException {
+ final Request request = chain.request();
+ final String cacheKey = calculateCacheKey(request.url().toString());
+ if (k8sEnabled && !urlCache.containsKey(cacheKey)) {
+ //first call (no information) / kubernetes token is applicable
+ final Request altered;
+ try {
+ altered = buildRequest(request, k8sAuthHeaderSupplier.get(), false);
+ } catch (IllegalStateException|IllegalArgumentException ex) {
+ final Request fallbackRequest = buildRequest(request, fallbackAuthHeaderSupplier.get(), true);
+ return doRequestFallback(fallbackRequest, KUBERNETES_TOKEN_ACQUISITION_ERROR, cacheKey, chain);
+ }
+ final Response response = chain.proceed(altered);
+ if (response.code() == HTTP_UNAUTHORIZED) {
+ //authentication failed, need to use old approach
+ response.close();
+ final Request fallbackRequest = buildRequest(request, fallbackAuthHeaderSupplier.get(), true);
+ return doRequestFallback(fallbackRequest, KUBERNETES_TOKEN_UNAUTHORIZED_ERROR, cacheKey, chain);
+ }
+ return response;
+ }
+ final Request fallbackRequest = buildRequest(request, fallbackAuthHeaderSupplier.get(), true);
+ return chain.proceed(fallbackRequest);
+ }
+
+ private Response doRequestFallback(final Request fallbackRequest,
+ final String reason,
+ final String cacheKey,
+ final Interceptor.Chain chain) throws IOException {
+ final Response fallbackResponse = chain.proceed(fallbackRequest);
+ if (fallbackResponse.isSuccessful()) {
+ urlCache.store(cacheKey);
+ if(k8sEnabled && Objects.equals(reason, KUBERNETES_TOKEN_ACQUISITION_ERROR)) {
+ log.warn("Failed to establish m2m connection to {}\n{}", fallbackRequest.url(), reason);
+ } else {
+ log.debug("Failed to establish m2m connection to {}\n{}", fallbackRequest.url(), reason);
+ }
+ }
+ return fallbackResponse;
+ }
+
+ private Request buildRequest(final Request initialRequest, final String authHeader, final boolean useFallbackUrl) {
+ if (StringUtils.isEmpty(authHeader)) {
+ throw new IllegalStateException("M2M auth header is empty.");
+ }
+ HttpUrl targetUrl = initialRequest.url();
+ if(k8sEnabled && useFallbackUrl && fallbackBaseUrl != null) {
+ targetUrl = rebaseUrl(initialRequest.url(), fallbackBaseUrl);
+ }
+ return initialRequest.newBuilder()
+ .url(targetUrl)
+ .header("Authorization", authHeader)
+ .build();
+ }
+
+ private static HttpUrl rebaseUrl(final HttpUrl original, final HttpUrl base) {
+ return original.newBuilder()
+ .scheme(base.scheme())
+ .host(base.host())
+ .port(base.port())
+ .build();
+ }
+}
diff --git a/core-utils/k8s/src/main/java/com/netcracker/cloud/security/core/utils/k8s/impl/UrlCache.java b/core-utils/k8s/src/main/java/com/netcracker/cloud/security/core/utils/k8s/impl/UrlCache.java
new file mode 100644
index 000000000..8c518fcec
--- /dev/null
+++ b/core-utils/k8s/src/main/java/com/netcracker/cloud/security/core/utils/k8s/impl/UrlCache.java
@@ -0,0 +1,90 @@
+package com.netcracker.cloud.security.core.utils.k8s.impl;
+
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public class UrlCache {
+ private static final String INTERNAL_GATEWAY = "internal-gateway";
+ private static final int CACHE_SIZE = 400;
+ private static final long CACHE_DURATION_SECONDS = TimeUnit.HOURS.toSeconds(5);
+ private final Cache cache;
+
+ public UrlCache() {
+ this(CACHE_SIZE, CACHE_DURATION_SECONDS);
+ }
+
+ public UrlCache(final int cacheSize, final long ttlSeconds) {
+ this.cache = Caffeine.newBuilder()
+ .maximumSize(cacheSize)
+ .expireAfterAccess(ttlSeconds, TimeUnit.SECONDS)
+ .build();
+ }
+
+ public void store(@NotNull final String key) {
+ cache.put(key, Boolean.TRUE);
+ }
+
+ public boolean containsKey(@NotNull final String key) {
+ return cache.getIfPresent(key) != null;
+ }
+
+ public static String calculateCacheKey(final String rawUrl) {
+ URI parsedURI;
+ try {
+ parsedURI = new URI(rawUrl);
+ } catch (Exception ex) {
+ throw new IllegalArgumentException("Failed during parsing of URL: ", ex);
+ }
+ return calculateCacheKey(parsedURI);
+ }
+
+ public static String calculateCacheKey(final URI parsedURI) {
+ return parsedURI.getHost().contains(INTERNAL_GATEWAY)
+ ? calculateCacheKeyForInternalGateway(parsedURI)
+ : parsedURI.getHost() + ":" + parsedURI.getPort();
+ }
+
+ private static String calculateCacheKeyForInternalGateway(final URI parsedUri) {
+ final String[] segments = StringUtils.strip(parsedUri.getPath(), "/").split("/");
+ final List filteredSegments = new ArrayList<>();
+
+ String version = "";
+ String serviceName = "";
+
+ for (String segment : segments) {
+ if (StringUtils.isNotEmpty(version)) {
+ serviceName = segment;
+ break;
+ }
+ filteredSegments.add(segment);
+ if (isVersion(segment)) {
+ version = segment;
+ }
+ }
+
+ if (StringUtils.isEmpty(version)) {
+ log.debug("internal-gateway url does not contain any version; whole path will be used as a key for m2m decision cache");
+ }
+ String key = parsedUri.getHost() + ":" + parsedUri.getPort() + "/" + StringUtils.join(filteredSegments, "/");
+ if (parsedUri.getPath().startsWith("/api") && StringUtils.isNotEmpty(serviceName)) {
+ key = key + "/" + serviceName;
+ }
+
+ return key;
+ }
+
+ private static boolean isVersion(final String segment) {
+ if (segment.length() < 2 || segment.charAt(0) != 'v')
+ return false;
+ return segment.substring(1).matches("\\d+");
+ }
+}
diff --git a/core-utils/k8s/src/test/java/com/netcracker/cloud/security/core/utils/k8s/impl/M2MInterceptorTest.java b/core-utils/k8s/src/test/java/com/netcracker/cloud/security/core/utils/k8s/impl/M2MInterceptorTest.java
new file mode 100644
index 000000000..88098981d
--- /dev/null
+++ b/core-utils/k8s/src/test/java/com/netcracker/cloud/security/core/utils/k8s/impl/M2MInterceptorTest.java
@@ -0,0 +1,185 @@
+package com.netcracker.cloud.security.core.utils.k8s.impl;
+
+import org.junit.jupiter.api.Test;
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.WireMock;
+import lombok.SneakyThrows;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.mockito.Mockito;
+
+import java.util.function.Supplier;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.when;
+
+class M2MInterceptorTest {
+ private static final String TEST_ENDPOINT = "/test/endpoint";
+ private static final int TEST_CACHE_SIZE = 10;
+ private static final long TEST_CACHE_DURATION_SEC = 60;
+
+ private WireMockServer wireMockServer;
+ private OkHttpClient client;
+
+ private Supplier fallbackSupplier;
+ private Supplier k8sSupplier;
+
+ private static final String K8S_TOKEN_HEADER = "Bearer k8s-test-token";
+ private static final String FALLBACK_TOKEN_HEADER = "Bearer fallback-test-token";
+
+ @BeforeEach
+ @SuppressWarnings("unchecked")
+ void beforeEach() {
+ System.setProperty("security.m2m.kubernetes.enabled", "true");
+
+ wireMockServer = new WireMockServer(0);
+ wireMockServer.start();
+ WireMock.configureFor("localhost", wireMockServer.port());
+
+ UrlCache urlCache = new UrlCache(TEST_CACHE_SIZE, TEST_CACHE_DURATION_SEC);
+ fallbackSupplier = Mockito.mock(Supplier.class);
+ k8sSupplier = Mockito.mock(Supplier.class);
+
+ // Default behavior: return valid tokens
+ when(k8sSupplier.get()).thenReturn(K8S_TOKEN_HEADER);
+ when(fallbackSupplier.get()).thenReturn(FALLBACK_TOKEN_HEADER);
+
+ final M2MInterceptor interceptor = new M2MInterceptor(urlCache, fallbackSupplier, k8sSupplier);
+
+ client = new OkHttpClient.Builder()
+ .addInterceptor(interceptor)
+ .build();
+ }
+
+ @AfterEach
+ void afterEach() {
+ wireMockServer.stop();
+ System.clearProperty("security.m2m.kubernetes.enabled");
+ }
+
+ @Test
+ @SneakyThrows
+ void kubernetesTokenAuth_Success() {
+ stubFor(get(urlEqualTo(TEST_ENDPOINT))
+ .withHeader("Authorization", equalTo(K8S_TOKEN_HEADER))
+ .willReturn(aResponse().withStatus(200)));
+
+ try (Response response = client.newCall(buildRequest()).execute()) {
+ assertEquals(200, response.code());
+ }
+
+ verify(1, getRequestedFor(urlEqualTo(TEST_ENDPOINT)));
+ }
+
+ @Test
+ @SneakyThrows
+ void keycloakTokenAuth_UnauthorizedFallback() {
+ // 1. First call with K8s token returns 401
+ stubFor(get(urlEqualTo(TEST_ENDPOINT))
+ .withHeader("Authorization", equalTo(K8S_TOKEN_HEADER))
+ .willReturn(aResponse().withStatus(401)));
+
+ // 2. Fallback call with Keycloak token returns 200
+ stubFor(get(urlEqualTo(TEST_ENDPOINT))
+ .withHeader("Authorization", equalTo(FALLBACK_TOKEN_HEADER))
+ .willReturn(aResponse().withStatus(200)));
+
+ try (Response response = client.newCall(buildRequest()).execute()) {
+ assertEquals(200, response.code());
+ }
+
+ // Verify both requests were made
+ verify(1, getRequestedFor(urlEqualTo(TEST_ENDPOINT)).withHeader("Authorization", equalTo(K8S_TOKEN_HEADER)));
+ verify(1, getRequestedFor(urlEqualTo(TEST_ENDPOINT)).withHeader("Authorization", equalTo(FALLBACK_TOKEN_HEADER)));
+
+ // 3. Second call should go STRAIGHT to fallback because URL is now cached as "non-k8s"
+ try (Response response = client.newCall(buildRequest()).execute()) {
+ assertEquals(200, response.code());
+ }
+
+ // Total count for fallback should be 2, but K8s should still be 1
+ verify(1, getRequestedFor(urlEqualTo(TEST_ENDPOINT)).withHeader("Authorization", equalTo(K8S_TOKEN_HEADER)));
+ verify(2, getRequestedFor(urlEqualTo(TEST_ENDPOINT)).withHeader("Authorization", equalTo(FALLBACK_TOKEN_HEADER)));
+ }
+
+ @Test
+ @SneakyThrows
+ void kubernetesTokenAcquisitionError_Fallback() {
+ // Simulate acquisition error
+ when(k8sSupplier.get()).thenThrow(new IllegalStateException("K8s failed"));
+
+ stubFor(get(urlEqualTo(TEST_ENDPOINT))
+ .withHeader("Authorization", equalTo(FALLBACK_TOKEN_HEADER))
+ .willReturn(aResponse().withStatus(200)));
+
+ try (Response response = client.newCall(buildRequest()).execute()) {
+ assertEquals(200, response.code());
+ }
+
+ // Verify it never tried K8s at the network level and went straight to fallback
+ verify(0, getRequestedFor(urlEqualTo(TEST_ENDPOINT)).withHeader("Authorization", equalTo(K8S_TOKEN_HEADER)));
+ verify(1, getRequestedFor(urlEqualTo(TEST_ENDPOINT)).withHeader("Authorization", equalTo(FALLBACK_TOKEN_HEADER)));
+ }
+
+ @Test
+ @SneakyThrows
+ void bothTokensEmpty_ThrowsException() {
+ when(k8sSupplier.get()).thenReturn("");
+ when(fallbackSupplier.get()).thenReturn("");
+
+ assertThrows(IllegalStateException.class, () -> {
+ client.newCall(buildRequest()).execute();
+ });
+ }
+
+ private Request buildRequest() {
+ return new Request.Builder()
+ .url(wireMockServer.baseUrl() + TEST_ENDPOINT)
+ .get()
+ .build();
+ }
+
+ @Test
+ @SneakyThrows
+ void fallbackUrl_RebasesHostWhenFallbackOccurs() {
+ WireMockServer fallbackServer = new WireMockServer(0);
+ fallbackServer.start();
+ WireMock.configureFor("localhost", fallbackServer.port());
+
+ fallbackServer.stubFor(get(urlEqualTo(TEST_ENDPOINT))
+ .withHeader("Authorization", equalTo(FALLBACK_TOKEN_HEADER))
+ .willReturn(aResponse().withStatus(200)));
+
+ wireMockServer.stubFor(get(urlEqualTo(TEST_ENDPOINT))
+ .withHeader("Authorization", equalTo(K8S_TOKEN_HEADER))
+ .willReturn(aResponse().withStatus(401)));
+
+ UrlCache urlCache = new UrlCache(TEST_CACHE_SIZE, TEST_CACHE_DURATION_SEC);
+ String fallbackBaseUrl = "http://localhost:" + fallbackServer.port();
+
+ M2MInterceptor interceptor = new M2MInterceptor(urlCache, fallbackSupplier, k8sSupplier, fallbackBaseUrl);
+ OkHttpClient clientWithFallbackUrl = new OkHttpClient.Builder()
+ .addInterceptor(interceptor)
+ .build();
+
+ Request request = new Request.Builder()
+ .url(wireMockServer.baseUrl() + TEST_ENDPOINT)
+ .get()
+ .build();
+
+ try (Response response = clientWithFallbackUrl.newCall(request).execute()) {
+ assertEquals(200, response.code());
+ }
+
+ wireMockServer.verify(1, getRequestedFor(urlEqualTo(TEST_ENDPOINT))
+ .withHeader("Authorization", equalTo(K8S_TOKEN_HEADER)));
+ fallbackServer.verify(1, getRequestedFor(urlEqualTo(TEST_ENDPOINT))
+ .withHeader("Authorization", equalTo(FALLBACK_TOKEN_HEADER)));
+
+ fallbackServer.stop();
+ }
+}
diff --git a/core-utils/k8s/src/test/java/com/netcracker/cloud/security/core/utils/k8s/impl/UrlCacheTest.java b/core-utils/k8s/src/test/java/com/netcracker/cloud/security/core/utils/k8s/impl/UrlCacheTest.java
new file mode 100644
index 000000000..8c2d3bb01
--- /dev/null
+++ b/core-utils/k8s/src/test/java/com/netcracker/cloud/security/core/utils/k8s/impl/UrlCacheTest.java
@@ -0,0 +1,38 @@
+package com.netcracker.cloud.security.core.utils.k8s.impl;
+
+import org.junit.jupiter.api.Test;
+
+import static com.netcracker.cloud.security.core.utils.k8s.impl.UrlCache.calculateCacheKey;
+import static org.junit.jupiter.api.Assertions.*;
+
+class UrlCacheTest {
+
+ @Test
+ void calculateCacheKeyTest() {
+ String key = calculateCacheKey("https://internal-gateway:3030/api/v1/service-a/resource/123");
+ assertEquals("internal-gateway:3030/api/v1/service-a", key);
+
+ key = calculateCacheKey("https://internal-gateway:3030/api/v1");
+ assertEquals("internal-gateway:3030/api/v1", key);
+
+ key = calculateCacheKey("https://internal-gateway:3030/custom-prefix/api/v2/module-b/action");
+ assertEquals("internal-gateway:3030/custom-prefix/api/v2", key);
+
+ key = calculateCacheKey("https://internal-gateway:3030/long/complex/path/v3/target/item");
+ assertEquals("internal-gateway:3030/long/complex/path/v3", key);
+
+ key = calculateCacheKey("https://internal-gateway:3030/api/v/resource");
+ assertEquals("internal-gateway:3030/api/v/resource", key);
+
+ key = calculateCacheKey("https://internal-gateway:3030/api/vv/resource");
+ assertEquals("internal-gateway:3030/api/vv/resource", key);
+
+ key = calculateCacheKey("https://internal-gateway:3030/api/v1/service?query=param&data=true");
+ assertEquals("internal-gateway:3030/api/v1/service", key);
+
+ key = calculateCacheKey("https://external-service:8080/api/v1/resource");
+ assertEquals("external-service:8080", key);
+
+ assertThrows(IllegalArgumentException.class, () -> calculateCacheKey("illegal characters here"));
+ }
+}
diff --git a/core-utils/k8s/src/test/resources/logback.xml b/core-utils/k8s/src/test/resources/logback.xml
index 9fa50918a..473e4e83e 100644
--- a/core-utils/k8s/src/test/resources/logback.xml
+++ b/core-utils/k8s/src/test/resources/logback.xml
@@ -1,17 +1,19 @@
-
-
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n
-
+
+
+
+
+
diff --git a/dbaas-client/dbaas-client-java/dbaas-client-core/src/main/java/com/netcracker/cloud/dbaas/client/config/DbaasClientConfiguration.java b/dbaas-client/dbaas-client-java/dbaas-client-core/src/main/java/com/netcracker/cloud/dbaas/client/config/DbaasClientConfiguration.java
index c4ffd1a9d..3781a5832 100644
--- a/dbaas-client/dbaas-client-java/dbaas-client-core/src/main/java/com/netcracker/cloud/dbaas/client/config/DbaasClientConfiguration.java
+++ b/dbaas-client/dbaas-client-java/dbaas-client-core/src/main/java/com/netcracker/cloud/dbaas/client/config/DbaasClientConfiguration.java
@@ -78,4 +78,3 @@ DbaasClassifierFactory dbaasClassifierFactory(MSInfoProvider msInfoProvider) {
return new DbaasClassifierFactory(msInfoProvider);
}
}
-
diff --git a/dbaas-client/dbaas-client-java/dbaas-client-core/src/main/java/com/netcracker/cloud/dbaas/client/config/SpringDbaasApiProperties.java b/dbaas-client/dbaas-client-java/dbaas-client-core/src/main/java/com/netcracker/cloud/dbaas/client/config/SpringDbaasApiProperties.java
index d71c3687b..eff84933d 100644
--- a/dbaas-client/dbaas-client-java/dbaas-client-core/src/main/java/com/netcracker/cloud/dbaas/client/config/SpringDbaasApiProperties.java
+++ b/dbaas-client/dbaas-client-java/dbaas-client-core/src/main/java/com/netcracker/cloud/dbaas/client/config/SpringDbaasApiProperties.java
@@ -2,17 +2,27 @@
import lombok.AccessLevel;
import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import java.util.Optional;
+@Slf4j
@Getter
public class SpringDbaasApiProperties {
private static final String DEFAULT_DBAAS_AGENT_URL = "http://dbaas-agent:8080";
@Getter(AccessLevel.NONE)
@Value("${dbaas.api.address:#{null}}")
- private Optional address;
+ private Optional dbaasAgentAddress;
+
+ @Getter(AccessLevel.NONE)
+ @Value("${api.dbaas.address:#{null}}")
+ private Optional dbaasAddress;
+
+ @Getter(AccessLevel.NONE)
+ @Value("${security.m2m.kubernetes.enabled:false}")
+ private boolean k8sEnabled;
@Value("${dbaas.api.retry.default.template.maxAttempts:10}")
private int dbaasDefaultRetryMaxAttempts;
@@ -24,6 +34,13 @@ public class SpringDbaasApiProperties {
private int dbaasAsyncRetryTimeoutInS;
public String getAddress() {
- return address.orElse(DEFAULT_DBAAS_AGENT_URL);
+ if(!k8sEnabled) {
+ return dbaasAgentAddress.orElse(DEFAULT_DBAAS_AGENT_URL);
+ }
+ if(dbaasAddress.isEmpty()) {
+ log.warn("DBaaS address is not available, falling back to dbaas-agent. Specify 'api.dbaas.address' property to DBaaS url");
+ return dbaasAgentAddress.orElse(DEFAULT_DBAAS_AGENT_URL);
+ }
+ return dbaasAddress.get();
}
}
diff --git a/dbaas-client/dbaas-client-java/dbaas-client-core/src/test/java/com/netcracker/cloud/dbaas/client/DbaasClientRetryTest.java b/dbaas-client/dbaas-client-java/dbaas-client-core/src/test/java/com/netcracker/cloud/dbaas/client/DbaasClientRetryTest.java
index 1dce9d926..01881957c 100644
--- a/dbaas-client/dbaas-client-java/dbaas-client-core/src/test/java/com/netcracker/cloud/dbaas/client/DbaasClientRetryTest.java
+++ b/dbaas-client/dbaas-client-java/dbaas-client-core/src/test/java/com/netcracker/cloud/dbaas/client/DbaasClientRetryTest.java
@@ -12,6 +12,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.net.URI;
@@ -22,6 +23,7 @@
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {TestDbaasCoreConfiguration.class})
+@TestPropertySource(properties = "api.dbaas.address=http://ms-name.namespace:8080")
public class DbaasClientRetryTest {
@Autowired
diff --git a/dbaas-client/dbaas-client-java/dbaas-client-core/src/test/resources/application.yml b/dbaas-client/dbaas-client-java/dbaas-client-core/src/test/resources/application.yml
index 3aefce013..31acfef01 100644
--- a/dbaas-client/dbaas-client-java/dbaas-client-core/src/test/resources/application.yml
+++ b/dbaas-client/dbaas-client-java/dbaas-client-core/src/test/resources/application.yml
@@ -1,3 +1,7 @@
spring:
main:
- allow-bean-definition-overriding: true
\ No newline at end of file
+ allow-bean-definition-overriding: true
+
+api:
+ dbaas:
+ address: http://ms-name.namespace:8080
diff --git a/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-resttemplate/pom.xml b/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-resttemplate/pom.xml
index 3ce967a3b..05610bb9b 100644
--- a/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-resttemplate/pom.xml
+++ b/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-resttemplate/pom.xml
@@ -31,6 +31,16 @@
com.netcracker.cloud.security.core.utils
tls-utils
+
+ com.netcracker.cloud.security.core.utils
+ k8s-utils
+ 3.1.0-SNAPSHOT
+
+
+ com.netcracker.cloud
+ microservice-restclient-okhttp
+ 7.1.0-SNAPSHOT
+
diff --git a/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-resttemplate/src/main/java/com/netcracker/cloud/dbaas/client/restclient/resttemplate/DbaasRestTemplateConfiguration.java b/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-resttemplate/src/main/java/com/netcracker/cloud/dbaas/client/restclient/resttemplate/DbaasRestTemplateConfiguration.java
index ad19034dd..d98ae7464 100644
--- a/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-resttemplate/src/main/java/com/netcracker/cloud/dbaas/client/restclient/resttemplate/DbaasRestTemplateConfiguration.java
+++ b/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-resttemplate/src/main/java/com/netcracker/cloud/dbaas/client/restclient/resttemplate/DbaasRestTemplateConfiguration.java
@@ -1,9 +1,11 @@
package com.netcracker.cloud.dbaas.client.restclient.resttemplate;
import com.netcracker.cloud.restclient.MicroserviceRestClient;
+import com.netcracker.cloud.restclient.okhttp.MicroserviceOkHttpRestClient;
import com.netcracker.cloud.restclient.resttemplate.MicroserviceRestTemplate;
import com.netcracker.cloud.restlegacy.resttemplate.configuration.annotation.EnableFrameworkRestTemplate;
-import org.springframework.beans.factory.annotation.Qualifier;
+import com.netcracker.cloud.security.core.auth.M2MManager;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -14,7 +16,8 @@
@ConditionalOnProperty(value = "dbaas.restclient.resttemplate.basic-auth", havingValue = "false", matchIfMissing = true)
public class DbaasRestTemplateConfiguration {
@Bean("dbaasRestClient")
- public MicroserviceRestClient dbaasRestClient(@Qualifier("m2mRestTemplate") RestTemplate restTemplate){
- return new MicroserviceRestTemplate(restTemplate);
+ public MicroserviceRestClient dbaasRestClient(M2MManager m2MManager){
+ var client = M2MClientFactory.getDbaasOkHttpClient(() -> m2MManager.getToken().getTokenValue());
+ return new MicroserviceOkHttpRestClient(client);
}
}
diff --git a/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-webclient/pom.xml b/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-webclient/pom.xml
index ca793b544..e1fa7af4f 100644
--- a/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-webclient/pom.xml
+++ b/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-webclient/pom.xml
@@ -18,6 +18,16 @@
webclient
${project.groupId}
+
+ com.netcracker.cloud.security.core.utils
+ k8s-utils
+ 3.1.0-SNAPSHOT
+
+
+ com.netcracker.cloud
+ microservice-restclient-okhttp
+ 7.1.0-SNAPSHOT
+
diff --git a/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-webclient/src/main/java/com/netcracker/cloud/dbaas/client/restclient/webclient/DbaasWebClientConfiguration.java b/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-webclient/src/main/java/com/netcracker/cloud/dbaas/client/restclient/webclient/DbaasWebClientConfiguration.java
index c47208395..54de766f2 100644
--- a/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-webclient/src/main/java/com/netcracker/cloud/dbaas/client/restclient/webclient/DbaasWebClientConfiguration.java
+++ b/dbaas-client/dbaas-client-java/dbaas-client-restclient/dbaas-client-webclient/src/main/java/com/netcracker/cloud/dbaas/client/restclient/webclient/DbaasWebClientConfiguration.java
@@ -1,13 +1,13 @@
package com.netcracker.cloud.dbaas.client.restclient.webclient;
-import com.fasterxml.jackson.databind.DeserializationFeature;
import com.netcracker.cloud.restclient.MicroserviceRestClient;
-import com.netcracker.cloud.restclient.webclient.MicroserviceWebClient;
+import com.netcracker.cloud.restclient.okhttp.MicroserviceOkHttpRestClient;
+import com.netcracker.cloud.security.core.auth.M2MManager;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import com.netcracker.cloud.smartclient.config.annotation.EnableFrameworkWebClient;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
@@ -19,18 +19,9 @@
public class DbaasWebClientConfiguration {
@Bean("dbaasRestClient")
- public MicroserviceRestClient dbaasRestClient(@Qualifier("m2mWebClient") WebClient webClient) {
- WebClient customizedWebClient = webClient.mutate()
- .filters(new DisableHttpTraceFilterConsumer())
- .codecs(clientCodecsConfigurer -> clientCodecsConfigurer.defaultCodecs()
- .configureDefaultCodec(o -> {
- if (o instanceof Jackson2JsonDecoder decoder) {
- decoder.getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- }
- }))
- .build();
-
- return new MicroserviceWebClient(customizedWebClient);
+ public MicroserviceRestClient dbaasRestClient(M2MManager m2MManager) {
+ var client = M2MClientFactory.getDbaasOkHttpClient(() -> m2MManager.getToken().getTokenValue());
+ return new MicroserviceOkHttpRestClient(client);
}
// If sleuth enabled, it tries to get db health from http filters. But dataSource can be not initialized yet.
diff --git a/maas-client/client/pom.xml b/maas-client/client/pom.xml
index 30fada87f..a45cafea5 100644
--- a/maas-client/client/pom.xml
+++ b/maas-client/client/pom.xml
@@ -53,6 +53,11 @@
org.slf4j
slf4j-api
+
+ com.netcracker.cloud.security.core.utils
+ k8s-utils
+ 3.1.0-SNAPSHOT
+
diff --git a/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/Env.java b/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/Env.java
index c9aa5694c..3e32738e0 100644
--- a/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/Env.java
+++ b/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/Env.java
@@ -23,20 +23,32 @@ public class Env {
static final String ENV_CLOUD_NAMESPACE = "CLOUD_NAMESPACE";
static final String ENV_ORIGIN_NAMESPACE = "ORIGIN_NAMESPACE";
static final String ENV_MICROSERVICE_NAME = "MICROSERVICE_NAME";
+ static final String ENV_K8S_ENABLED = "SECURITY_M2M_KUBERNETES_ENABLED";
public static final String PROP_CLOUD_NAMESPACE = "cloud.microservice.namespace";
public static final String PROP_NAMESPACE = "maas.client.classifier.namespace"; //todo deprecated - delete in the next major release
public static final String PROP_ORIGIN_NAMESPACE = "origin_namespace"; //todo change to 'origin.namespace'
- public static final String PROP_API_URL = "maas.client.api.url";
+ public static final String PROP_MAAS_AGENT_URL = "maas.client.api.url";
+ public static final String PROP_MAAS_URL = "maas.internal.address";
public static final String PROP_API_AUTH = "maas.client.api.auth";
public static final String PROP_TENANT_MANAGER_URL = "maas.client.tenant-manager.url";
public static final String PROP_TENANT_MANAGER_RECONNECT_TIMEOUT = "maas.client.tenant-manager.reconnect-timeout";
public static final String PROP_HTTP_TIMEOUT = "maas.http.timeout";
public static String apiUrl() {
- return stringProperty(PROP_API_URL)
+ boolean k8sEnabled = Boolean.parseBoolean(System.getenv().get(ENV_K8S_ENABLED));
+ String maasAgentUrl = stringProperty(PROP_MAAS_AGENT_URL)
.map(Env::normalizeUrl)
.orElse(addr2http("maas-agent"));
+ if(!k8sEnabled) {
+ return maasAgentUrl;
+ }
+ return stringProperty(PROP_MAAS_URL)
+ .map(Env::normalizeUrl)
+ .orElseGet(() -> {
+ log.warn("MaaS address is not available, falling back to maas-agent. Specify '{}'property to MaaS url", PROP_MAAS_URL);
+ return maasAgentUrl;
+ });
}
public static String apiAuth() {
diff --git a/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/MaaSAPIClientImpl.java b/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/MaaSAPIClientImpl.java
index 49a66ad8e..e8717678b 100644
--- a/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/MaaSAPIClientImpl.java
+++ b/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/MaaSAPIClientImpl.java
@@ -20,14 +20,14 @@ public class MaaSAPIClientImpl implements MaaSAPIClient {
private final ApiUrlProvider apiProvider;
public MaaSAPIClientImpl(Supplier tokenSupplier) {
- this.restClient = new HttpClient(tokenSupplier);
+ this.restClient = HttpClient.getMaasClient(tokenSupplier);
this.serverApiVersion = new ServerApiVersion(restClient, Env.apiUrl());
- this.tenantManagerConnector = new Lazy<>(() -> new TenantManagerConnectorImpl(restClient));
+ this.tenantManagerConnector = new Lazy<>(() -> new TenantManagerConnectorImpl(HttpClient.getM2mClient(tokenSupplier)));
this.apiProvider = new ApiUrlProvider(serverApiVersion, Env.apiUrl());
}
public MaaSAPIClientImpl(Supplier tokenSupplier, TenantManagerConnector tenantManagerConnector, BlueGreenStatePublisher statePublisher) {
- this.restClient = new HttpClient(tokenSupplier);
+ this.restClient = HttpClient.getMaasClient(tokenSupplier);
this.serverApiVersion = new ServerApiVersion(restClient, Env.apiUrl());
this.tenantManagerConnector = new Lazy<>(() -> tenantManagerConnector);
this.apiProvider = new ApiUrlProvider(serverApiVersion, Env.apiUrl());
diff --git a/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/http/HttpClient.java b/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/http/HttpClient.java
index a7b2f366d..c19152069 100644
--- a/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/http/HttpClient.java
+++ b/maas-client/client/src/main/java/com/netcracker/cloud/maas/client/impl/http/HttpClient.java
@@ -2,6 +2,7 @@
import com.netcracker.cloud.context.propagation.core.RequestContextPropagation;
import com.netcracker.cloud.maas.client.impl.Env;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import okhttp3.OkHttpClient;
import okhttp3.Request;
@@ -10,16 +11,21 @@
public class HttpClient {
private final OkHttpClient httpClient;
- public HttpClient(Supplier tokenSupplier) {
- this.httpClient = new OkHttpClient.Builder()
+ public static HttpClient getM2mClient(Supplier tokenSupplier) {
+ return new HttpClient(M2MClientFactory.getM2mOkHttpClient(tokenSupplier));
+ }
+
+ public static HttpClient getMaasClient(Supplier tokenSupplier) {
+ return new HttpClient(M2MClientFactory.getMaasOkHttpClient(tokenSupplier));
+ }
+
+ private HttpClient(OkHttpClient client) {
+ this.httpClient = client.newBuilder()
.addInterceptor(chain -> {
Request.Builder reqBuilder = chain.request().newBuilder();
// dump context
RequestContextPropagation.populateResponse((key, value) -> reqBuilder.header(key, String.valueOf(value)));
-
- // add authorization token
- reqBuilder.header("Authorization", Env.apiAuth() + " " + tokenSupplier.get());
Env.namespaceOpt().ifPresent(ns -> reqBuilder.header("X-Origin-Namespace", ns));
// process request
diff --git a/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/EnvTest.java b/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/EnvTest.java
index 31048b5ad..205e9ed5b 100644
--- a/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/EnvTest.java
+++ b/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/EnvTest.java
@@ -11,25 +11,38 @@
class EnvTest {
@Test
void testApiUrl() {
- withProp(Env.PROP_API_URL, null, () ->
+ withProp(Env.PROP_MAAS_AGENT_URL, null, () ->
assertEquals("http://maas-agent:8080", Env.apiUrl())
);
}
@Test
void testApiUrlOverride() {
- withProp(Env.PROP_API_URL, "http://localhost:8080/", () ->
+ withProp(Env.PROP_MAAS_AGENT_URL, "http://localhost:8080/", () ->
assertEquals("http://localhost:8080", Env.apiUrl())
);
}
@Test
void testApiUrlWrongOverride() {
- withProp(Env.PROP_API_URL, "localhost:8080", () ->
- assertThrows(IllegalArgumentException.class, () -> Env.apiUrl())
+ withProp(Env.PROP_MAAS_AGENT_URL, "localhost:8080", () ->
+ assertThrows(IllegalArgumentException.class, Env::apiUrl)
);
}
+ @Test
+ void testApiUrlK8sEnabled() throws Exception {
+ withEnvironmentVariable(Env.ENV_K8S_ENABLED, "true")
+ .execute(() -> {
+ withProp(Env.PROP_MAAS_AGENT_URL, null, () ->
+ assertEquals("http://maas-agent:8080", Env.apiUrl())
+ );
+ withProp(Env.PROP_MAAS_URL, "http://localhost:8080/", () ->
+ assertEquals( "http://localhost:8080", Env.apiUrl())
+ );
+ });
+ }
+
@Test
void testTenantManagerReconnectTimeoutDefaults() {
withProp(Env.PROP_TENANT_MANAGER_RECONNECT_TIMEOUT, null, () ->
diff --git a/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/apiversion/ServerApiVersionTest.java b/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/apiversion/ServerApiVersionTest.java
index fa0809339..251b1ccab 100644
--- a/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/apiversion/ServerApiVersionTest.java
+++ b/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/apiversion/ServerApiVersionTest.java
@@ -2,6 +2,7 @@
import com.netcracker.cloud.maas.client.Utils;
import com.netcracker.cloud.maas.client.impl.http.HttpClient;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockserver.integration.ClientAndServer;
@@ -50,7 +51,9 @@ private ServerApiVersion setup(ClientAndServer mockServer, String version) {
.withBody(Utils.readResourceAsString("api-version." + version + ".json"))
);
- var httpClient = new HttpClient(() -> "faketoken");
+ System.setProperty(M2MClientFactory.MAAS_AGENT_URL_PROP, "http://localhost:" + mockServer.getPort());
+ var httpClient = HttpClient.getMaasClient(() -> "faketoken");
+ System.clearProperty(M2MClientFactory.MAAS_AGENT_URL_PROP);
return new ServerApiVersion(httpClient, "http://localhost:" + mockServer.getPort());
}
}
diff --git a/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/kafka/KafkaMaaSClientImplTest.java b/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/kafka/KafkaMaaSClientImplTest.java
index f02a69d18..c9f295634 100644
--- a/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/kafka/KafkaMaaSClientImplTest.java
+++ b/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/kafka/KafkaMaaSClientImplTest.java
@@ -17,6 +17,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -546,7 +547,7 @@ public void testGetOrCreateTopicV2(ClientAndServer mockServer) {
@Test
void testWatchTopicCreate(ClientAndServer mockServer) throws InterruptedException {
withProp(Env.PROP_NAMESPACE, "cloud-dev", () -> {
- withProp(Env.PROP_API_URL, "http://localhost:" + mockServer.getPort(), () -> {
+ withProp(Env.PROP_MAAS_AGENT_URL, "http://localhost:" + mockServer.getPort(), () -> {
HttpRequest req = request().withMethod("POST").withPath("/api/v2/kafka/topic/watch-create");
ExpectationResponseCallback respWithError = httpRequest -> {
@@ -581,7 +582,7 @@ void testWatchTopicCreate(ClientAndServer mockServer) throws InterruptedExceptio
@Test
void testTopicDeleteSuccess(ClientAndServer mockServer) throws Exception {
withProp(Env.PROP_NAMESPACE, "cloud-dev", () -> {
- withProp(Env.PROP_API_URL, "http://localhost:" + mockServer.getPort(), () -> {
+ withProp(Env.PROP_MAAS_AGENT_URL, "http://localhost:" + mockServer.getPort(), () -> {
mockServer.when(
request().withMethod("DELETE").withPath("/api/v2/kafka/topic"), Times.once()
@@ -604,7 +605,7 @@ void testTopicDeleteSuccess(ClientAndServer mockServer) throws Exception {
@Test
void testTopicDeleteError(ClientAndServer mockServer) throws Exception {
withProp(Env.PROP_NAMESPACE, "cloud-dev", () -> {
- withProp(Env.PROP_API_URL, "http://localhost:" + mockServer.getPort(), () -> {
+ withProp(Env.PROP_MAAS_AGENT_URL, "http://localhost:" + mockServer.getPort(), () -> {
mockServer.when(
request().withMethod("DELETE").withPath("/api/v2/kafka/topic"),
@@ -764,8 +765,10 @@ void testSearchTopic(ClientAndServer mockServer) {
}
private KafkaMaaSClientImpl createKafkaClient(String agentUrl) {
- var httpClient = new HttpClient(() -> "faketoken");
+ System.setProperty(M2MClientFactory.MAAS_AGENT_URL_PROP, agentUrl);
+ var httpClient = HttpClient.getMaasClient(() -> "faketoken");
var serverApiVersion = new ServerApiVersion(httpClient, agentUrl);
+ System.clearProperty(M2MClientFactory.MAAS_AGENT_URL_PROP);
return new KafkaMaaSClientImpl(
httpClient,
diff --git a/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/kafka/KafkaWatchTenantTopicsTest.java b/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/kafka/KafkaWatchTenantTopicsTest.java
index 58af89501..6920aa8c1 100644
--- a/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/kafka/KafkaWatchTenantTopicsTest.java
+++ b/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/kafka/KafkaWatchTenantTopicsTest.java
@@ -5,6 +5,7 @@
import com.netcracker.cloud.maas.client.impl.Env;
import com.netcracker.cloud.maas.client.impl.apiversion.ServerApiVersion;
import com.netcracker.cloud.maas.client.impl.http.HttpClient;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import com.netcracker.cloud.tenantmanager.client.impl.TenantManagerConnectorImpl;
import com.netcracker.cloud.testharness.MaaSCocoonExtension;
import com.netcracker.cloud.testharness.TenantManagerMockInject;
@@ -50,13 +51,15 @@ public void resetMOckServer(ClientAndServer mockServer) {
@Test
public void testWatchEvents(ClientAndServer mockServer) throws Exception {
withProp(Env.PROP_NAMESPACE, "core-dev", () -> {
- HttpClient httpClient = new HttpClient(() -> "faketoken");
- var agentUrl = "http://localhost:" + mockServer.getPort();
+ var agentUrl = "http://localhost:" + mockServer.getPort();
+ System.setProperty(M2MClientFactory.MAAS_AGENT_URL_PROP, agentUrl);
+
+ HttpClient httpClient = HttpClient.getMaasClient(() -> "faketoken");
var serverApiVersion = new ServerApiVersion(httpClient, agentUrl);
KafkaMaaSClientImpl client = new KafkaMaaSClientImpl(
httpClient,
- () -> new TenantManagerConnectorImpl(tmMock.getUrl(), httpClient),
+ () -> new TenantManagerConnectorImpl(tmMock.getUrl(), HttpClient.getM2mClient(() -> "faketoken")),
new ApiUrlProvider(serverApiVersion, agentUrl));
BlockingQueue> events = new LinkedBlockingDeque<>();
@@ -130,11 +133,13 @@ public void testWatchEvents(ClientAndServer mockServer) throws Exception {
@Test
public void testWatchEvents_ButTopicsNotFoundInMaaS(ClientAndServer mockServer) throws Exception {
withProp(Env.PROP_NAMESPACE, "core-dev", () -> {
- HttpClient httpClient = new HttpClient(() -> "faketoken");
- var agentUrl = "http://localhost:" + mockServer.getPort();
+ var agentUrl = "http://localhost:" + mockServer.getPort();
+ System.setProperty(M2MClientFactory.MAAS_AGENT_URL_PROP, agentUrl);
+
+ HttpClient httpClient = HttpClient.getMaasClient(() -> "faketoken");
KafkaMaaSClientImpl client = new KafkaMaaSClientImpl(
httpClient,
- () -> new TenantManagerConnectorImpl(tmMock.getUrl(), httpClient),
+ () -> new TenantManagerConnectorImpl(tmMock.getUrl(), HttpClient.getM2mClient(() -> "faketoken")),
new ApiUrlProvider(new ServerApiVersion(httpClient, agentUrl), agentUrl));
BlockingQueue> events = new LinkedBlockingDeque<>();
diff --git a/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/rabbit/RabbitMaaSClientImplTest.java b/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/rabbit/RabbitMaaSClientImplTest.java
index 6badea5fb..1ac1a1390 100644
--- a/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/rabbit/RabbitMaaSClientImplTest.java
+++ b/maas-client/client/src/test/java/com/netcracker/cloud/maas/client/impl/rabbit/RabbitMaaSClientImplTest.java
@@ -7,6 +7,7 @@
import com.netcracker.cloud.maas.client.impl.Env;
import com.netcracker.cloud.maas.client.impl.apiversion.ServerApiVersion;
import com.netcracker.cloud.maas.client.impl.http.HttpClient;
+import com.netcracker.cloud.security.core.utils.k8s.M2MClientFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -146,6 +147,8 @@ public void testGetVHost(ClientAndServer mockServer) {
assertEquals("scott", vhost.getUsername());
assertEquals("tiger", vhost.getPassword());
assertEquals("http://rabbit-cluster:15672/api", vhost.getApiUrl());
+
+ System.clearProperty(Env.PROP_NAMESPACE);
}
@Test
@@ -217,7 +220,8 @@ public void testVersionedQueueName1() {
}
private RabbitMaaSClientImpl createRabbitClient(String agentUrl) {
- var httpClient = new HttpClient(() -> "faketoken");
+ System.setProperty(M2MClientFactory.MAAS_AGENT_URL_PROP, agentUrl);
+ var httpClient = HttpClient.getMaasClient(() -> "faketoken");
var serverApiVersion = new ServerApiVersion(httpClient, agentUrl);
return new RabbitMaaSClientImpl(httpClient, new ApiUrlProvider(serverApiVersion, agentUrl));
diff --git a/maas-client/client/src/test/java/com/netcracker/cloud/tenantmanager/client/impl/TenantManagerConnectorImplTest.java b/maas-client/client/src/test/java/com/netcracker/cloud/tenantmanager/client/impl/TenantManagerConnectorImplTest.java
index dac2283d9..4596bf1c2 100644
--- a/maas-client/client/src/test/java/com/netcracker/cloud/tenantmanager/client/impl/TenantManagerConnectorImplTest.java
+++ b/maas-client/client/src/test/java/com/netcracker/cloud/tenantmanager/client/impl/TenantManagerConnectorImplTest.java
@@ -31,7 +31,7 @@ class TenantManagerConnectorImplTest {
@Test
public void testApi() throws Exception {
BlockingQueue> events = new LinkedBlockingDeque<>();
- try (TenantManagerConnectorImpl client = new TenantManagerConnectorImpl(tmMock.getUrl(), new HttpClient(() -> "faketoken"))) {
+ try (TenantManagerConnectorImpl client = new TenantManagerConnectorImpl(tmMock.getUrl(), HttpClient.getM2mClient(() -> "faketoken"))) {
client.subscribe(events::add);
List tenants = events.poll(1, TimeUnit.SECONDS);
assertNotNull(tenants);
@@ -66,7 +66,7 @@ public void testApi() throws Exception {
public void testReconnect() throws Exception {
withProp(Env.PROP_TENANT_MANAGER_RECONNECT_TIMEOUT, "1", () -> {
BlockingQueue> events = new LinkedBlockingDeque<>();
- try (TenantManagerConnectorImpl client = new TenantManagerConnectorImpl(tmMock.getUrl(), new HttpClient(() -> "faketoken"))) {
+ try (TenantManagerConnectorImpl client = new TenantManagerConnectorImpl(tmMock.getUrl(), HttpClient.getM2mClient(() -> "faketoken"))) {
client.subscribe(events::add);
List tenants = events.poll(1, TimeUnit.SECONDS);
diff --git a/maas-declarative-client-quarkus/maas-kafka-quarkus-client/runtime/src/main/java/com/netcracker/maas/declarative/kafka/quarkus/client/config/MaasKafkaProdClientConfig.java b/maas-declarative-client-quarkus/maas-kafka-quarkus-client/runtime/src/main/java/com/netcracker/maas/declarative/kafka/quarkus/client/config/MaasKafkaProdClientConfig.java
index 48b2d690c..fce4f4131 100644
--- a/maas-declarative-client-quarkus/maas-kafka-quarkus-client/runtime/src/main/java/com/netcracker/maas/declarative/kafka/quarkus/client/config/MaasKafkaProdClientConfig.java
+++ b/maas-declarative-client-quarkus/maas-kafka-quarkus-client/runtime/src/main/java/com/netcracker/maas/declarative/kafka/quarkus/client/config/MaasKafkaProdClientConfig.java
@@ -21,7 +21,7 @@ public class MaasKafkaProdClientConfig {
@Singleton
@Produces
KafkaMaaSClient kafkaMaaSClient(MaasKafkaProps props, M2MManager m2mManager) {
- HttpClient httpClient = new HttpClient(() -> m2mManager.getToken().getTokenValue());
+ HttpClient httpClient = HttpClient.getM2mClient(() -> m2mManager.getToken().getTokenValue());
return new KafkaMaaSClientImpl(
httpClient,
() -> new TenantManagerConnectorImpl(httpClient),
@@ -41,7 +41,7 @@ MaasKafkaTopicServiceProvider maasKafkaTopicServiceProvider(KafkaMaaSClient kafk
@Produces
@DefaultBean
InternalTenantService internalTenantService(M2MManager m2mManager) {
- HttpClient httpClient = new HttpClient(() -> m2mManager.getToken().getTokenValue());
+ HttpClient httpClient = HttpClient.getM2mClient(() -> m2mManager.getToken().getTokenValue());
TenantManagerConnectorImpl tenantManagerConnector = new TenantManagerConnectorImpl(httpClient);
return new InternalTenantServiceImpl(tenantManagerConnector);
}
diff --git a/maas-declarative-client-spring/maas-kafka-spring-client/src/main/java/com/netcracker/maas/declarative/kafka/spring/client/config/MaasKafkaProdClientConfig.java b/maas-declarative-client-spring/maas-kafka-spring-client/src/main/java/com/netcracker/maas/declarative/kafka/spring/client/config/MaasKafkaProdClientConfig.java
index 46d95d69c..7dae07738 100644
--- a/maas-declarative-client-spring/maas-kafka-spring-client/src/main/java/com/netcracker/maas/declarative/kafka/spring/client/config/MaasKafkaProdClientConfig.java
+++ b/maas-declarative-client-spring/maas-kafka-spring-client/src/main/java/com/netcracker/maas/declarative/kafka/spring/client/config/MaasKafkaProdClientConfig.java
@@ -29,12 +29,12 @@ public class MaasKafkaProdClientConfig {
@Bean
HttpClient maasHttpClient(@Autowired M2MManager m2MManager) {
- return new HttpClient(() -> m2MManager.getToken().getTokenValue());
+ return HttpClient.getMaasClient(() -> m2MManager.getToken().getTokenValue());
}
@Bean
- TenantManagerConnector tenantManagerConnector(HttpClient httpClient) {
- return new TenantManagerConnectorImpl(httpClient);
+ TenantManagerConnector tenantManagerConnector(@Autowired M2MManager m2MManager) {
+ return new TenantManagerConnectorImpl(HttpClient.getM2mClient(() -> m2MManager.getToken().getTokenValue()));
}
@Bean