diff --git a/gravitee-apim-definition/gravitee-apim-definition-model/pom.xml b/gravitee-apim-definition/gravitee-apim-definition-model/pom.xml
index d09b4d0ad38..73f1a1003f0 100644
--- a/gravitee-apim-definition/gravitee-apim-definition-model/pom.xml
+++ b/gravitee-apim-definition/gravitee-apim-definition-model/pom.xml
@@ -47,6 +47,10 @@
io.gravitee.node
gravitee-node-vertx
+
+ io.gravitee.secret
+ gravitee-secret-api
+
diff --git a/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/jks/JKSKeyStore.java b/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/jks/JKSKeyStore.java
index d456d440e1c..470bc36ef32 100644
--- a/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/jks/JKSKeyStore.java
+++ b/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/jks/JKSKeyStore.java
@@ -17,6 +17,8 @@
import io.gravitee.definition.model.v4.ssl.KeyStore;
import io.gravitee.definition.model.v4.ssl.KeyStoreType;
+import io.gravitee.secrets.api.annotation.Secret;
+import io.gravitee.secrets.api.el.FieldKind;
import java.io.Serial;
import lombok.Builder;
import lombok.Getter;
@@ -36,8 +38,13 @@ public class JKSKeyStore extends KeyStore {
private String path;
private String content;
+
+ @Secret(FieldKind.PASSWORD)
private String password;
+
private String alias;
+
+ @Secret(FieldKind.PASSWORD)
private String keyPassword;
public JKSKeyStore() {
diff --git a/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/jks/JKSTrustStore.java b/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/jks/JKSTrustStore.java
index baec82a1e6a..f9a1d02efa2 100644
--- a/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/jks/JKSTrustStore.java
+++ b/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/jks/JKSTrustStore.java
@@ -17,6 +17,8 @@
import io.gravitee.definition.model.v4.ssl.TrustStore;
import io.gravitee.definition.model.v4.ssl.TrustStoreType;
+import io.gravitee.secrets.api.annotation.Secret;
+import io.gravitee.secrets.api.el.FieldKind;
import java.io.Serial;
import lombok.Builder;
import lombok.Getter;
@@ -36,7 +38,10 @@ public class JKSTrustStore extends TrustStore {
private String path;
private String content;
+
+ @Secret(FieldKind.PASSWORD)
private String password;
+
private String alias;
public JKSTrustStore() {
diff --git a/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pem/PEMKeyStore.java b/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pem/PEMKeyStore.java
index a34b8da40a9..a240e9ba6c6 100644
--- a/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pem/PEMKeyStore.java
+++ b/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pem/PEMKeyStore.java
@@ -17,6 +17,8 @@
import io.gravitee.definition.model.v4.ssl.KeyStore;
import io.gravitee.definition.model.v4.ssl.KeyStoreType;
+import io.gravitee.secrets.api.annotation.Secret;
+import io.gravitee.secrets.api.el.FieldKind;
import java.io.Serial;
import lombok.Builder;
import lombok.Getter;
@@ -35,7 +37,10 @@ public class PEMKeyStore extends KeyStore {
private static final long serialVersionUID = 1051430527272519608L;
private String keyPath;
+
+ @Secret(FieldKind.PRIVATE_KEY)
private String keyContent;
+
private String certPath;
private String certContent;
diff --git a/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pkcs12/PKCS12KeyStore.java b/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pkcs12/PKCS12KeyStore.java
index 9e4c26de7e4..8ada39027ce 100644
--- a/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pkcs12/PKCS12KeyStore.java
+++ b/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pkcs12/PKCS12KeyStore.java
@@ -17,6 +17,8 @@
import io.gravitee.definition.model.v4.ssl.KeyStore;
import io.gravitee.definition.model.v4.ssl.KeyStoreType;
+import io.gravitee.secrets.api.annotation.Secret;
+import io.gravitee.secrets.api.el.FieldKind;
import java.io.Serial;
import lombok.Builder;
import lombok.Getter;
@@ -36,7 +38,10 @@ public class PKCS12KeyStore extends KeyStore {
private String path;
private String content;
+
+ @Secret(FieldKind.PASSWORD)
private String password;
+
private String alias;
/**
diff --git a/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pkcs12/PKCS12TrustStore.java b/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pkcs12/PKCS12TrustStore.java
index 5b9dd22a6d0..8d3367db4de 100644
--- a/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pkcs12/PKCS12TrustStore.java
+++ b/gravitee-apim-definition/gravitee-apim-definition-model/src/main/java/io/gravitee/definition/model/v4/ssl/pkcs12/PKCS12TrustStore.java
@@ -17,6 +17,8 @@
import io.gravitee.definition.model.v4.ssl.TrustStore;
import io.gravitee.definition.model.v4.ssl.TrustStoreType;
+import io.gravitee.secrets.api.annotation.Secret;
+import io.gravitee.secrets.api.el.FieldKind;
import java.io.Serial;
import lombok.Builder;
import lombok.Getter;
@@ -36,7 +38,10 @@ public class PKCS12TrustStore extends TrustStore {
private String path;
private String content;
+
+ @Secret(FieldKind.PASSWORD)
private String password;
+
private String alias;
public PKCS12TrustStore() {
diff --git a/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/http/secrets/SecretsV4IntegrationTest.java b/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/http/secrets/SecretsV4IntegrationTest.java
new file mode 100644
index 00000000000..84de79c64d4
--- /dev/null
+++ b/gravitee-apim-integration-tests/src/test/java/io/gravitee/apim/integration/tests/http/secrets/SecretsV4IntegrationTest.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright © 2015 The Gravitee team (http://gravitee.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.gravitee.apim.integration.tests.http.secrets;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import com.graviteesource.entrypoint.http.get.HttpGetEntrypointConnectorFactory;
+import com.graviteesource.secretprovider.hcvault.HCVaultSecretProvider;
+import com.graviteesource.secretprovider.hcvault.HCVaultSecretProviderFactory;
+import com.graviteesource.secretprovider.hcvault.config.manager.VaultConfig;
+import com.graviteesource.service.secrets.SecretsService;
+import io.gravitee.apim.gateway.tests.sdk.AbstractGatewayTest;
+import io.gravitee.apim.gateway.tests.sdk.annotations.DeployApi;
+import io.gravitee.apim.gateway.tests.sdk.annotations.GatewayTest;
+import io.gravitee.apim.gateway.tests.sdk.configuration.GatewayConfigurationBuilder;
+import io.gravitee.apim.gateway.tests.sdk.connector.EndpointBuilder;
+import io.gravitee.apim.gateway.tests.sdk.connector.EntrypointBuilder;
+import io.gravitee.apim.gateway.tests.sdk.secrets.SecretProviderBuilder;
+import io.gravitee.apim.gateway.tests.sdk.utils.ResourceUtils;
+import io.gravitee.common.service.AbstractService;
+import io.gravitee.definition.model.v4.Api;
+import io.gravitee.definition.model.v4.endpointgroup.Endpoint;
+import io.gravitee.gateway.reactor.ReactableApi;
+import io.gravitee.node.secrets.plugins.SecretProviderPlugin;
+import io.gravitee.plugin.endpoint.EndpointConnectorPlugin;
+import io.gravitee.plugin.endpoint.http.proxy.HttpProxyEndpointConnectorFactory;
+import io.gravitee.plugin.entrypoint.EntrypointConnectorPlugin;
+import io.gravitee.plugin.entrypoint.http.proxy.HttpProxyEntrypointConnectorFactory;
+import io.gravitee.secrets.api.plugin.SecretManagerConfiguration;
+import io.gravitee.secrets.api.plugin.SecretProviderFactory;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.rxjava3.core.Vertx;
+import io.vertx.rxjava3.core.http.HttpClient;
+import io.vertx.rxjava3.core.http.HttpClientRequest;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Test;
+import org.testcontainers.containers.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.vault.VaultContainer;
+
+/**
+ * @author Remi Baptiste (remi.baptiste at graviteesource.com)
+ * @author GraviteeSource Team
+ */
+@Testcontainers
+@GatewayTest
+public class SecretsV4IntegrationTest extends AbstractGatewayTest {
+
+ private static final String VAULT_TOKEN = UUID.randomUUID().toString();
+
+ @org.testcontainers.junit.jupiter.Container
+ protected static final VaultContainer vaultContainer = new VaultContainer<>("hashicorp/vault:1.13.3")
+ .withVaultToken(VAULT_TOKEN)
+ .withInitCommand(
+ "kv put secret/test private-key='-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCMOMvaM1XZzR1H\nPp127syCvuxnljnxsMLCvfM+8QsdyeuYVURei3z502zxWVTwNbxUbTxOkgIuNYRT\nyypEMpYajSEv0sMt4d7KBchE0eeQlcMDQ2J6kzfVjHyxLMMu8JscBQ5KGvF1vW3Q\np16w6C6JebF21Y0LumL9cMEToN6OrDKx9BrUkbTXHfSf+5rvkrnGfIPMulNJS2On\nl4zmT0bHs8a/zSIGmcwNIG243LmXTFu67TKbknJahICrRz0uZ8h1HMFbe7yY12s0\nd0xGJDJcPIBcdWHhB8z6iduTxCYZ2vY3EdFcC2RMO99zJPlWeDGY4lTM8TRFEAvE\nj4a21CltAgMBAAECggEADu4VNnx0zaX7UhSmq30tpVYy0ay7KrLJafbTqYX8ywUu\n4p9hkjeD7Q3H8cKzOoheLxcabrs5JDZqiol9TJmeReF1ASSNx5rfH9+RvVIkN87a\nXsST/b0jGsfElxDPD3Zq7YbUSKupvgGXaboIaQmvus+MR7zhMbh8xcN1q2NbjxE6\nCLXV+uu8kVPLsUbGFGK53vK7+MHnEKJIbjHR+LRNMxZRzoX7h57UO6uoXwWes2Kr\nopMzIJdv2ZRvXS62NNCTK9BoPb4OreXSoEJZkXS26ispOLLnM36D4UpNeDl6hITN\noCSHKiRGFqY5QOir/MP8uqNmGEtprMDmUQt/K5Z8OQKBgQDVvEi7SmHFJLNSsY2l\nvvxlwIa9rr0d/TFtTXcGMUdLYg7rQtaZ3e0geJv4wU58KahmpgYqpX4s0/Gc4L37\nyG1kCtPUjHvxxauLRr0OcXz35pTqlGhVGyls9onCxM/nDpoiYDvueuse69rVVGDE\nTKg2pxqS0Rxh7FARKY1RpJprjwKBgQCn8xsrRSc5QGF/L7b87MK1sf+lQ7Updubt\nv/XRFq5lhHp888MrIsqcqsDqRChoY2Qoi0vuNv52pgpha6lXkxL5Djd1ypX457KR\ntaJmx7qoolYW7INU4mvcryyIiW9ELiFrGb8XrwhXwmUBWOGGEDJkgYOj6W7Co38T\n2RbkBvBNQwKBgGTniv7A0v+bn/0+Tb0eOVJgXjxWrnnl+tu7YqHNyfbQyHJRD7d8\nimJ2DkyWFlOP5yzu3KJtlu/a74o8n/SqXtqIMhF6cVlnFOGf98lF0tXGSi+k+MyV\nEi2bBtaoy+4tep8YB7NC3JWwi5ODTlveRNvocCc4CcpBIlu33jvZFf4JAoGATJ0R\nn8OECRHdZ++UQfyfNdNlEza3xZp/7aTLtf3qwFSWq7lnJp5QXvdl2XgOFtCAOB6T\nHK/plKZZxece8Nweo45grlMj5s+LHf0FgG1MMPEc5IgvwOEo4xrl7cMEBs4kYH72\nNQ+bdq0u9lZdSpLI6iBKtNMfu5pptdwqHQstQ5ECgYBQ+XWJHuKLadcMAoAdG+gW\n5KxlSlin7PqgmzobXggp2aUGVLHs4pvIGA+7Sf/kAPfJ6bimv4dIODqEe8TZnmWp\n4ZG0jYjFXVnbwbh+hU5EF03ntO9WYqL6rYU3zujz/ZuKBEByIFowTX9uaVKEgML6\n5oHAF4Sb7zxa2jSEehGQ5Q==\n-----END PRIVATE KEY-----'"
+ );
+
+ private static String token;
+
+ private final int backendPort = getAvailablePort();
+
+ @Override
+ protected void configureWireMock(WireMockConfiguration configuration) {
+ configuration
+ .httpsPort(backendPort)
+ .needClientAuth(true)
+ .keystorePath(ResourceUtils.toPath("certs/keystore01.jks"))
+ .keystorePassword("password")
+ .trustStorePath(ResourceUtils.toPath("certs/truststore01.jks"))
+ .trustStorePassword("password");
+ }
+
+ @Override
+ public void configureEntrypoints(Map> entrypoints) {
+ entrypoints.putIfAbsent("http-proxy", EntrypointBuilder.build("http-proxy", HttpProxyEntrypointConnectorFactory.class));
+ }
+
+ @Override
+ public void configureEndpoints(Map> endpoints) {
+ endpoints.putIfAbsent("http-proxy", EndpointBuilder.build("http-proxy", HttpProxyEndpointConnectorFactory.class));
+ }
+
+ @Override
+ public void configureGateway(GatewayConfigurationBuilder configurationBuilder) {
+ super.configureGateway(configurationBuilder);
+
+ // create a renewable token so the plugin does not start panicking
+ Container.ExecResult execResult = null;
+ try {
+ execResult = vaultContainer.execInContainer("vault", "token", "create", "-period=10m", "-field", "token");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ token = execResult.getStdout();
+
+ configurationBuilder.setYamlProperty("api.secrets.providers[0].plugin", "vault");
+ configurationBuilder.setYamlProperty("api.secrets.providers[0].configuration.enabled", true);
+ configurationBuilder.setYamlProperty("api.secrets.providers[0].configuration.host", vaultContainer.getHost());
+ configurationBuilder.setYamlProperty("api.secrets.providers[0].configuration.port", vaultContainer.getMappedPort(8200));
+ configurationBuilder.setYamlProperty("api.secrets.providers[0].configuration.ssl.enabled", "false");
+ configurationBuilder.setYamlProperty("api.secrets.providers[0].configuration.auth.method", "token");
+ configurationBuilder.setYamlProperty("api.secrets.providers[0].configuration.auth.config.token", token);
+ }
+
+ @Override
+ public void configureSecretProviders(
+ Set, ? extends SecretManagerConfiguration>> secretProviderPlugins
+ ) {
+ secretProviderPlugins.add(
+ SecretProviderBuilder.build(HCVaultSecretProvider.PLUGIN_ID, HCVaultSecretProviderFactory.class, VaultConfig.class)
+ );
+ }
+
+ @Override
+ public void configureServices(Set>> services) {
+ super.configureServices(services);
+ services.add(SecretsService.class);
+ }
+
+ @AfterAll
+ static void cleanup() {
+ vaultContainer.close();
+ }
+
+ @Override
+ public void configureApi(ReactableApi> reactableApi, Class> definitionClass) {
+ if (!isV4Api(definitionClass)) {
+ throw new AssertionError("TCP api should only be v4 api");
+ }
+ final Api apiDefinition = (Api) reactableApi.getDefinition();
+
+ updateEndpointsPort(apiDefinition, backendPort);
+ }
+
+ @Test
+ @DeployApi({ "/apis/v4/http/secrets/api-secured-jks-password-secret-static-ref.json" })
+ void should_retrieve_password_from_secret_provider(HttpClient httpClient, Vertx vertx) {
+ wiremock.stubFor(get("/endpoint").willReturn(ok("response from backend")));
+
+ httpClient
+ .rxRequest(HttpMethod.GET, "/test")
+ .flatMap(HttpClientRequest::rxSend)
+ .flatMap(response -> {
+ // just asserting we get a response (hence no SSL errors), no need for an API.
+ assertThat(response.statusCode()).isEqualTo(200);
+ return response.body();
+ })
+ .test()
+ .awaitDone(10, TimeUnit.SECONDS)
+ .assertComplete();
+ //wiremock.verify(1, getRequestedFor(urlPathEqualTo("/endpoint")).withHeader("Authorization", equalTo("ApiKey ".concat(apiKey))));
+ }
+}
diff --git a/gravitee-apim-integration-tests/src/test/resources/apis/v4/http/secrets/api-secured-jks-password-secret-static-ref.json b/gravitee-apim-integration-tests/src/test/resources/apis/v4/http/secrets/api-secured-jks-password-secret-static-ref.json
new file mode 100644
index 00000000000..e15ece194d8
--- /dev/null
+++ b/gravitee-apim-integration-tests/src/test/resources/apis/v4/http/secrets/api-secured-jks-password-secret-static-ref.json
@@ -0,0 +1,73 @@
+{
+ "id": "static-secret-api-v4",
+ "name": "my-secret-api-v4",
+ "gravitee": "4.0.0",
+ "type": "proxy",
+ "listeners": [
+ {
+ "type": "http",
+ "paths": [
+ {
+ "path": "/test"
+ }
+ ],
+ "entrypoints": [
+ {
+ "type": "http-proxy"
+ }
+ ]
+ }
+ ],
+ "endpointGroups": [
+ {
+ "name": "default-group",
+ "type": "http-proxy",
+ "endpoints": [
+ {
+ "name": "default",
+ "type": "http-proxy",
+ "weight": 1,
+ "inheritConfiguration": false,
+ "configuration": {
+ "target": "https://localhost:8080/endpoint"
+ },
+ "sharedConfigurationOverride": {
+ "http": {
+ "connectTimeout": 3000,
+ "readTimeout": 60000
+ },
+ "ssl": {
+ "trustAll": false,
+ "keyStore": {
+ "type": "PEM",
+ "certContent": "-----BEGIN CERTIFICATE-----\nMIICxzCCAa+gAwIBAgIEPvlKwjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDEwls\nb2NhbGhvc3QwHhcNMTgxMDA5MTU0MTAyWhcNMTkxMDA0MTU0MTAyWjAUMRIwEAYD\nVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCM\nOMvaM1XZzR1HPp127syCvuxnljnxsMLCvfM+8QsdyeuYVURei3z502zxWVTwNbxU\nbTxOkgIuNYRTyypEMpYajSEv0sMt4d7KBchE0eeQlcMDQ2J6kzfVjHyxLMMu8Jsc\nBQ5KGvF1vW3Qp16w6C6JebF21Y0LumL9cMEToN6OrDKx9BrUkbTXHfSf+5rvkrnG\nfIPMulNJS2Onl4zmT0bHs8a/zSIGmcwNIG243LmXTFu67TKbknJahICrRz0uZ8h1\nHMFbe7yY12s0d0xGJDJcPIBcdWHhB8z6iduTxCYZ2vY3EdFcC2RMO99zJPlWeDGY\n4lTM8TRFEAvEj4a21CltAgMBAAGjITAfMB0GA1UdDgQWBBQmmZF9umT5DGh4RgYX\nBQhzb6EkQTANBgkqhkiG9w0BAQsFAAOCAQEAW1QaHW4iYjUtjQik+nWD3Xktbm50\ns9PeAYSCp9an757dvzfO/vwJZE+1+grmsS0l/jxh8L0qsdjM5Qt4VmjK5CbikE2v\ne4Vt4o40tQOz8A7fNVVp5S33njgNbp1UMhnrFsHVZ6Aa8HHxisjliluVK1/YPl80\nKRs57GL4SyvELzmWhh7egndxdGYR9nbAbg1RQ+kJClqSS0BL5oQ4Xn4AGmU5839/\nZ1+N5qgNq2/BYOi6FsltL91US0FOLNxDBYqjwShGOJ1V6Lvh27YmSHViscph6GeZ\nkZ2xybRANymp0DSVER5J+D2RuJNtzp/zl//BJ3b19tpVpDTQ1ndzcSGPLg==\n-----END CERTIFICATE-----",
+ "keyContent": "{#secrets.get('/vault/secret/test:private-key')}"
+ },
+ "trustStore": {
+ "type": "PEM",
+ "content": "-----BEGIN CERTIFICATE-----\nMIICxzCCAa+gAwIBAgIEPvlKwjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDEwls\nb2NhbGhvc3QwHhcNMTgxMDA5MTU0MTAyWhcNMTkxMDA0MTU0MTAyWjAUMRIwEAYD\nVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCM\nOMvaM1XZzR1HPp127syCvuxnljnxsMLCvfM+8QsdyeuYVURei3z502zxWVTwNbxU\nbTxOkgIuNYRTyypEMpYajSEv0sMt4d7KBchE0eeQlcMDQ2J6kzfVjHyxLMMu8Jsc\nBQ5KGvF1vW3Qp16w6C6JebF21Y0LumL9cMEToN6OrDKx9BrUkbTXHfSf+5rvkrnG\nfIPMulNJS2Onl4zmT0bHs8a/zSIGmcwNIG243LmXTFu67TKbknJahICrRz0uZ8h1\nHMFbe7yY12s0d0xGJDJcPIBcdWHhB8z6iduTxCYZ2vY3EdFcC2RMO99zJPlWeDGY\n4lTM8TRFEAvEj4a21CltAgMBAAGjITAfMB0GA1UdDgQWBBQmmZF9umT5DGh4RgYX\nBQhzb6EkQTANBgkqhkiG9w0BAQsFAAOCAQEAW1QaHW4iYjUtjQik+nWD3Xktbm50\ns9PeAYSCp9an757dvzfO/vwJZE+1+grmsS0l/jxh8L0qsdjM5Qt4VmjK5CbikE2v\ne4Vt4o40tQOz8A7fNVVp5S33njgNbp1UMhnrFsHVZ6Aa8HHxisjliluVK1/YPl80\nKRs57GL4SyvELzmWhh7egndxdGYR9nbAbg1RQ+kJClqSS0BL5oQ4Xn4AGmU5839/\nZ1+N5qgNq2/BYOi6FsltL91US0FOLNxDBYqjwShGOJ1V6Lvh27YmSHViscph6GeZ\nkZ2xybRANymp0DSVER5J+D2RuJNtzp/zl//BJ3b19tpVpDTQ1ndzcSGPLg==\n-----END CERTIFICATE-----"
+ }
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "flows": [
+ {
+ "name": "flow-1",
+ "enabled": true,
+ "selectors": [
+ {
+ "type": "http",
+ "path": "/",
+ "pathOperator": "START_WITH",
+ "methods": ["GET"]
+ }
+ ]
+ }
+ ],
+ "analytics": {
+ "enabled": false
+ }
+}
diff --git a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/pom.xml b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/pom.xml
index bcf9e99c289..7d844ebb9a6 100644
--- a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/pom.xml
+++ b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/pom.xml
@@ -60,6 +60,25 @@
${project.version}
provided
+
+ io.gravitee.plugin
+ gravitee-plugin-annotation-processors
+ ${gravitee-plugin.version}
+ provided
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ provided
+
+
+
+ org.hibernate.validator
+ hibernate-validator
+ ${hibernate-validator.version}
+ provided
+
@@ -92,6 +111,25 @@
maven-assembly-plugin
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 1.7
+
+
+ add-source
+ generate-sources
+
+ add-source
+
+
+
+
+
+
+
+
+
diff --git a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorFactory.java b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorFactory.java
index 047dfa2d290..b398bb36395 100644
--- a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorFactory.java
+++ b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorFactory.java
@@ -16,14 +16,15 @@
package io.gravitee.plugin.endpoint.http.proxy;
import io.gravitee.common.http.HttpHeader;
-import io.gravitee.definition.model.v4.http.HttpProxyOptions;
import io.gravitee.el.TemplateEngine;
import io.gravitee.gateway.reactive.api.ConnectorMode;
import io.gravitee.gateway.reactive.api.connector.endpoint.sync.HttpEndpointSyncConnectorFactory;
import io.gravitee.gateway.reactive.api.context.DeploymentContext;
import io.gravitee.gateway.reactive.api.helper.PluginConfigurationHelper;
import io.gravitee.plugin.endpoint.http.proxy.configuration.HttpProxyEndpointConnectorConfiguration;
+import io.gravitee.plugin.endpoint.http.proxy.configuration.HttpProxyEndpointConnectorConfigurationEvaluator;
import io.gravitee.plugin.endpoint.http.proxy.configuration.HttpProxyEndpointConnectorSharedConfiguration;
+import io.gravitee.plugin.endpoint.http.proxy.configuration.HttpProxyEndpointConnectorSharedConfigurationEvaluator;
import java.util.List;
import java.util.Set;
import lombok.AllArgsConstructor;
@@ -51,15 +52,17 @@ public HttpProxyEndpointConnector createConnector(
final String sharedConfiguration
) {
try {
- return new HttpProxyEndpointConnector(
- eval(
- deploymentContext,
- connectorFactoryHelper.readConfiguration(HttpProxyEndpointConnectorConfiguration.class, configuration)
- ),
- eval(
- deploymentContext,
+ HttpProxyEndpointConnectorConfigurationEvaluator configurationEvaluator = new HttpProxyEndpointConnectorConfigurationEvaluator(
+ connectorFactoryHelper.readConfiguration(HttpProxyEndpointConnectorConfiguration.class, configuration)
+ );
+ HttpProxyEndpointConnectorSharedConfigurationEvaluator sharedConfigurationEvaluator =
+ new HttpProxyEndpointConnectorSharedConfigurationEvaluator(
connectorFactoryHelper.readConfiguration(HttpProxyEndpointConnectorSharedConfiguration.class, sharedConfiguration)
- )
+ );
+ return new HttpProxyEndpointConnector(
+ configurationEvaluator.evalNow(deploymentContext),
+ //Still need to use this method here since the evaluator do not support EL on Headers
+ eval(deploymentContext, sharedConfigurationEvaluator.evalNow(deploymentContext))
);
} catch (Exception e) {
log.error("Can't create connector because no valid configuration", e);
@@ -80,15 +83,8 @@ private HttpProxyEndpointConnectorSharedConfiguration eval(
final HttpProxyEndpointConnectorSharedConfiguration groupConfiguration
) {
final TemplateEngine templateEngine = deploymentContext.getTemplateEngine();
- final HttpProxyOptions proxyOptions = groupConfiguration.getProxyOptions();
final List headers = groupConfiguration.getHeaders();
- if (proxyOptions != null) {
- proxyOptions.setHost(eval(templateEngine, proxyOptions.getHost()));
- proxyOptions.setUsername(eval(templateEngine, proxyOptions.getUsername()));
- proxyOptions.setPassword(eval(templateEngine, proxyOptions.getPassword()));
- }
-
if (headers != null && !headers.isEmpty()) {
headers.forEach(httpHeader -> httpHeader.setValue(eval(templateEngine, httpHeader.getValue())));
}
diff --git a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/configuration/HttpProxyEndpointConnectorConfiguration.java b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/configuration/HttpProxyEndpointConnectorConfiguration.java
index bb5078252b8..08803bf25f4 100644
--- a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/configuration/HttpProxyEndpointConnectorConfiguration.java
+++ b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/configuration/HttpProxyEndpointConnectorConfiguration.java
@@ -16,6 +16,7 @@
package io.gravitee.plugin.endpoint.http.proxy.configuration;
import io.gravitee.gateway.reactive.api.connector.endpoint.EndpointConnectorConfiguration;
+import io.gravitee.plugin.annotation.ConfigurationEvaluator;
import lombok.Getter;
import lombok.Setter;
@@ -25,6 +26,7 @@
*/
@Getter
@Setter
+@ConfigurationEvaluator(attributePrefix = "gravitee.attributes.endpoint.httpProxy")
public class HttpProxyEndpointConnectorConfiguration implements EndpointConnectorConfiguration {
private String target;
diff --git a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/configuration/HttpProxyEndpointConnectorSharedConfiguration.java b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/configuration/HttpProxyEndpointConnectorSharedConfiguration.java
index 202a5a8bc9c..01a0a096750 100644
--- a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/configuration/HttpProxyEndpointConnectorSharedConfiguration.java
+++ b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/configuration/HttpProxyEndpointConnectorSharedConfiguration.java
@@ -21,6 +21,7 @@
import io.gravitee.definition.model.v4.http.HttpProxyOptions;
import io.gravitee.definition.model.v4.ssl.SslOptions;
import io.gravitee.gateway.reactive.api.connector.endpoint.EndpointConnectorSharedConfiguration;
+import io.gravitee.plugin.annotation.ConfigurationEvaluator;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
@@ -31,6 +32,7 @@
*/
@Getter
@Setter
+@ConfigurationEvaluator(attributePrefix = "gravitee.attributes.endpoint.httpProxy")
public class HttpProxyEndpointConnectorSharedConfiguration implements EndpointConnectorSharedConfiguration {
@JsonProperty("proxy")
diff --git a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorFactoryTest.java b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorFactoryTest.java
index 6ed10e36829..417defda620 100644
--- a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorFactoryTest.java
+++ b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorFactoryTest.java
@@ -21,11 +21,13 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.gravitee.definition.model.v4.http.HttpClientOptions;
+import io.gravitee.el.TemplateContext;
import io.gravitee.el.TemplateEngine;
import io.gravitee.gateway.reactive.api.ApiType;
import io.gravitee.gateway.reactive.api.ConnectorMode;
import io.gravitee.gateway.reactive.api.context.DeploymentContext;
import io.gravitee.gateway.reactive.api.helper.PluginConfigurationHelper;
+import io.reactivex.rxjava3.core.Maybe;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -46,13 +48,17 @@ class HttpProxyEndpointConnectorFactoryTest {
@Mock
private TemplateEngine templateEngine;
+ @Mock
+ private TemplateContext templateContext;
+
@Mock
private DeploymentContext deploymentContext;
@BeforeEach
void beforeEach() {
lenient().when(deploymentContext.getTemplateEngine()).thenReturn(templateEngine);
- lenient().when(templateEngine.convert(anyString())).thenAnswer(i -> i.getArgument(0));
+ lenient().when(templateEngine.getTemplateContext()).thenReturn(templateContext);
+ lenient().when(templateEngine.eval(anyString(), any())).thenAnswer(i -> Maybe.just(i.getArgument(0)));
cut = new HttpProxyEndpointConnectorFactory(new PluginConfigurationHelper(null, new ObjectMapper()));
}
@@ -85,10 +91,10 @@ void shouldCreateConnectorWithRightConfiguration() {
HttpProxyEndpointConnector connector = cut.createConnector(deploymentContext, CONFIG, SHARED_CONFIG);
assertThat(connector).isNotNull();
assertThat(connector.configuration).isNotNull();
- verify(templateEngine).convert("https://localhost:8082/echo?foo=bar");
- verify(templateEngine).convert("localhost");
- verify(templateEngine).convert("user");
- verify(templateEngine).convert("pwd");
+ verify(templateEngine).eval("https://localhost:8082/echo?foo=bar", String.class);
+ verify(templateEngine).eval("localhost", String.class);
+ verify(templateEngine).eval("user", String.class);
+ verify(templateEngine).eval("pwd", String.class);
verify(templateEngine).convert("Value1");
verify(templateEngine).convert("Value2");
}
diff --git a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorTest.java b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorTest.java
index 00d8003b524..25e84d227c5 100644
--- a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorTest.java
+++ b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/HttpProxyEndpointConnectorTest.java
@@ -29,9 +29,9 @@
import io.gravitee.gateway.reactive.api.ApiType;
import io.gravitee.gateway.reactive.api.ConnectorMode;
import io.gravitee.gateway.reactive.api.context.DeploymentContext;
-import io.gravitee.gateway.reactive.api.context.ExecutionContext;
-import io.gravitee.gateway.reactive.api.context.Request;
-import io.gravitee.gateway.reactive.api.context.Response;
+import io.gravitee.gateway.reactive.api.context.http.HttpExecutionContext;
+import io.gravitee.gateway.reactive.api.context.http.HttpRequest;
+import io.gravitee.gateway.reactive.api.context.http.HttpResponse;
import io.gravitee.gateway.reactive.api.tracing.Tracer;
import io.gravitee.node.opentelemetry.tracer.noop.NoOpTracer;
import io.gravitee.plugin.endpoint.http.proxy.client.GrpcHttpClientFactory;
@@ -69,13 +69,13 @@ class HttpProxyEndpointConnectorTest {
private TemplateEngine templateEngine;
@Mock
- private ExecutionContext ctx;
+ private HttpExecutionContext ctx;
@Mock
- private Request request;
+ private HttpRequest request;
@Mock
- private Response response;
+ private HttpResponse response;
@Mock
private Metrics metrics;
diff --git a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/client/HttpClientFactoryTest.java b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/client/HttpClientFactoryTest.java
index 44fe66d9580..8f68ee1c0a5 100644
--- a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/client/HttpClientFactoryTest.java
+++ b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/client/HttpClientFactoryTest.java
@@ -21,7 +21,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import io.gravitee.gateway.reactive.api.context.ExecutionContext;
+import io.gravitee.gateway.reactive.api.context.http.HttpExecutionContext;
import io.gravitee.node.api.configuration.Configuration;
import io.gravitee.plugin.endpoint.http.proxy.configuration.HttpProxyEndpointConnectorConfiguration;
import io.gravitee.plugin.endpoint.http.proxy.configuration.HttpProxyEndpointConnectorSharedConfiguration;
@@ -47,7 +47,7 @@ class HttpClientFactoryTest {
public static final int TIMEOUT_SECONDS = 60;
@Mock
- protected ExecutionContext ctx;
+ protected HttpExecutionContext ctx;
protected HttpClientFactory cut;
protected HttpProxyEndpointConnectorConfiguration configuration;
diff --git a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/connector/HttpConnectorTest.java b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/connector/HttpConnectorTest.java
index 2a912650ab2..2d64ef676a6 100644
--- a/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/connector/HttpConnectorTest.java
+++ b/gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/test/java/io/gravitee/plugin/endpoint/http/proxy/connector/HttpConnectorTest.java
@@ -46,9 +46,9 @@
import io.gravitee.gateway.api.http.HttpHeaders;
import io.gravitee.gateway.http.vertx.VertxHttpHeaders;
import io.gravitee.gateway.reactive.api.context.DeploymentContext;
-import io.gravitee.gateway.reactive.api.context.ExecutionContext;
-import io.gravitee.gateway.reactive.api.context.Request;
-import io.gravitee.gateway.reactive.api.context.Response;
+import io.gravitee.gateway.reactive.api.context.http.HttpExecutionContext;
+import io.gravitee.gateway.reactive.api.context.http.HttpRequest;
+import io.gravitee.gateway.reactive.api.context.http.HttpResponse;
import io.gravitee.gateway.reactive.api.tracing.Tracer;
import io.gravitee.node.api.configuration.Configuration;
import io.gravitee.node.opentelemetry.tracer.noop.NoOpTracer;
@@ -96,13 +96,13 @@ class HttpConnectorTest {
private TemplateEngine templateEngine;
@Mock
- private ExecutionContext ctx;
+ private HttpExecutionContext ctx;
@Mock
- private Request request;
+ private HttpRequest request;
@Mock
- private Response response;
+ private HttpResponse response;
@Mock
private Metrics metrics;
diff --git a/pom.xml b/pom.xml
index 2abffc552b6..9b5a22e38c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,7 +65,7 @@
7.0.1
1.4.3
1.4.0
- 4.3.1
+ 4.4.2
1.11.0
1.31.2
1.1.0