From b1063aa5cd336e7036bf308bf5c7fc602fdba739 Mon Sep 17 00:00:00 2001 From: Aliaksei Darafeyeu <adarafeyeu@slb.com> Date: Thu, 18 Feb 2021 15:04:40 -0500 Subject: [PATCH] adds support azure multi-tenancy --- devops/azure/chart/templates/deployment.yaml | 19 +- .../auth/EntitlementsClientFactory.java | 8 +- pom.xml | 2 +- provider/notification-aws/pom.xml | 2 +- provider/notification-azure/README.md | 2 + provider/notification-azure/pom.xml | 325 +++++++++--------- .../azure/util/AzureCosmosProperties.java | 69 ++-- .../provider/azure/util/HandshakeFilter.java | 93 ++--- .../provider/azure/util/Slf4jMDCFilter.java | 77 +++++ .../src/main/resources/application.properties | 32 +- .../util/AzureCosmosPropertiesTest.java | 83 ----- 11 files changed, 337 insertions(+), 375 deletions(-) create mode 100644 provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/Slf4jMDCFilter.java delete mode 100644 provider/notification-azure/src/test/java/org/opengroup/osdu/notification/util/AzureCosmosPropertiesTest.java diff --git a/devops/azure/chart/templates/deployment.yaml b/devops/azure/chart/templates/deployment.yaml index af7918321..dbddae713 100644 --- a/devops/azure/chart/templates/deployment.yaml +++ b/devops/azure/chart/templates/deployment.yaml @@ -52,6 +52,8 @@ spec: env: - name: spring_application_name value: notification-azure + - name: LOG_PREFIX + value: "notification" - name: server.servlet.contextPath value: /api/notification/v1 - name: server_port @@ -61,21 +63,6 @@ spec: configMapKeyRef: name: osdu-svc-properties key: ENV_KEYVAULT - - name: AZURE_TENANT_ID - valueFrom: - secretKeyRef: - name: active-directory - key: tenantid - - name: AZURE_CLIENT_ID - valueFrom: - secretKeyRef: - name: active-directory - key: principal-clientid - - name: AZURE_CLIENT_SECRET - valueFrom: - secretKeyRef: - name: active-directory - key: principal-clientpassword - name: aad_client_id valueFrom: secretKeyRef: @@ -92,5 +79,7 @@ spec: value: http://entitlements-azure/entitlements/v1 - name: registeration_service_endpoint value: http://register/api/register/v1 + - name: partition_service_endpoint + value: http://partition/api/partition/v1 - name: maxCacheSize value: "20" \ No newline at end of file diff --git a/notification-core/src/main/java/org/opengroup/osdu/notification/auth/EntitlementsClientFactory.java b/notification-core/src/main/java/org/opengroup/osdu/notification/auth/EntitlementsClientFactory.java index 53a5427d1..c5648d893 100644 --- a/notification-core/src/main/java/org/opengroup/osdu/notification/auth/EntitlementsClientFactory.java +++ b/notification-core/src/main/java/org/opengroup/osdu/notification/auth/EntitlementsClientFactory.java @@ -19,6 +19,7 @@ package org.opengroup.osdu.notification.auth; import org.opengroup.osdu.core.common.entitlements.EntitlementsAPIConfig; import org.opengroup.osdu.core.common.entitlements.EntitlementsFactory; import org.opengroup.osdu.core.common.entitlements.IEntitlementsFactory; +import org.opengroup.osdu.core.common.http.json.HttpResponseBodyMapper; import org.opengroup.osdu.notification.provider.interfaces.IAppProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AbstractFactoryBean; @@ -28,11 +29,14 @@ import org.springframework.stereotype.Component; public class EntitlementsClientFactory extends AbstractFactoryBean<IEntitlementsFactory> { @Autowired - private IAppProperties config; + private IAppProperties config; + @Autowired + private HttpResponseBodyMapper responseBodyMapper; @Override protected IEntitlementsFactory createInstance() { - return new EntitlementsFactory(EntitlementsAPIConfig.builder().rootUrl(config.getAuthorizeAPI()).build()); + return new EntitlementsFactory(EntitlementsAPIConfig.builder().rootUrl(config.getAuthorizeAPI()).build(), + responseBodyMapper); } @Override diff --git a/pom.xml b/pom.xml index 5d3e0c934..4caf96126 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ <java.version>8</java.version> <maven.compiler.target>${java.version}</maven.compiler.target> <maven.compiler.source>${java.version}</maven.compiler.source> - <os-core-common.version>0.3.6</os-core-common.version> + <os-core-common.version>0.3.27</os-core-common.version> </properties> <licenses> diff --git a/provider/notification-aws/pom.xml b/provider/notification-aws/pom.xml index 52bb168f5..5f7431a42 100644 --- a/provider/notification-aws/pom.xml +++ b/provider/notification-aws/pom.xml @@ -48,7 +48,7 @@ <dependency> <groupId>org.opengroup.osdu.core.aws</groupId> <artifactId>os-core-lib-aws</artifactId> - <version>0.3.14</version> + <version>0.6.0-SNAPSHOT</version> </dependency> <!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-secretsmanager --> diff --git a/provider/notification-azure/README.md b/provider/notification-azure/README.md index bacbd92b8..bd9d413bd 100644 --- a/provider/notification-azure/README.md +++ b/provider/notification-azure/README.md @@ -44,6 +44,8 @@ az keyvault secret show --vault-name $KEY_VAULT_NAME --name $KEY_VAULT_SECRET_NA | `azure.activedirectory.AppIdUri` | `api://${azure.activedirectory.client-id}` | URI for AAD Application | no | -- | | `azure.activedirectory.session-stateless` | `true` | Flag run in stateless mode (needed by AAD dependency) | no | -- | | `KEYVAULT_URI` | ex `https://foo-keyvault.vault.azure.net/` | URI of KeyVault that holds application secrets | no | output of infrastructure deployment | +| `PARTITION_API` | ex `https://foo-partition.azurewebsites.net` | Partition Service API endpoint | no | output of infrastructure deployment | +| `azure.activedirectory.app-resource-id` | `********` | AAD client application ID | yes | output of infrastructure deployment | ### Configure Maven diff --git a/provider/notification-azure/pom.xml b/provider/notification-azure/pom.xml index 33a86732c..51a326534 100644 --- a/provider/notification-azure/pom.xml +++ b/provider/notification-azure/pom.xml @@ -23,183 +23,168 @@ <description>Azure implementation for Notification service</description> <packaging>jar</packaging> - <parent> - <groupId>org.opengroup.osdu</groupId> - <artifactId>os-notification</artifactId> - <version>0.6.0-SNAPSHOT</version> - <relativePath>../../pom.xml</relativePath> - </parent> + <parent> + <groupId>org.opengroup.osdu</groupId> + <artifactId>os-notification</artifactId> + <version>0.6.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> - <properties> - <java.version>8</java.version> - <maven.compiler.target>${java.version}</maven.compiler.target> - <maven.compiler.source>${java.version}</maven.compiler.source> - <azure.version>2.1.7</azure.version> - <springframework.version>4.3.0.RELEASE</springframework.version> - <reactor.netty.version>0.9.0.RELEASE</reactor.netty.version> - <reactor.core.version>3.3.0.RELEASE</reactor.core.version> - </properties> + <properties> + <java.version>8</java.version> + <maven.compiler.target>${java.version}</maven.compiler.target> + <maven.compiler.source>${java.version}</maven.compiler.source> + <jacoco-maven-plugin.version>0.8.2</jacoco-maven-plugin.version> + <osdu.notification-core.version>0.6.0-SNAPSHOT</osdu.notification-core.version> + <springframework.version>4.3.0.RELEASE</springframework.version> + <reactor.netty.version>0.9.0.RELEASE</reactor.netty.version> + <reactor.core.version>3.3.0.RELEASE</reactor.core.version> + <osdu.corelibazure.version>0.0.66</osdu.corelibazure.version> + <junit.version>5.6.0</junit.version> + <jjwt.version>3.8.1</jjwt.version> + <mockito.version>2.23.0</mockito.version> + </properties> + <dependencyManagement> <dependencies> - <dependency> - <groupId>com.microsoft.azure</groupId> - <artifactId>azure-active-directory-spring-boot-starter</artifactId> - <version>${azure.version}</version> - </dependency> - - <dependency> - <groupId>org.opengroup.osdu</groupId> - <artifactId>os-core-common</artifactId> - <version>0.3.6</version> - </dependency> - - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-security</artifactId> - <exclusions> - <exclusion> - <groupId>ch.qos.logback</groupId> - <artifactId>logback-classic</artifactId> - </exclusion> - <exclusion> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-to-slf4j</artifactId> - </exclusion> - </exclusions> - </dependency> - - <dependency> - <groupId>org.opengroup.osdu</groupId> - <artifactId>core-lib-azure</artifactId> - <version>0.0.22</version> - </dependency> - - <dependency> - <groupId>com.auth0</groupId> - <artifactId>java-jwt</artifactId> - <version>3.8.1</version> - </dependency> - - <dependency> - <groupId>org.opengroup.osdu</groupId> - <artifactId>notification-core</artifactId> - <version>0.6.0-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>com.auth0</groupId> - <artifactId>java-jwt</artifactId> - <version>3.3.0</version> - </dependency> + <!-- Inherit managed dependencies from core-lib-azure --> + <dependency> + <groupId>org.opengroup.osdu</groupId> + <artifactId>core-lib-azure</artifactId> + <version>${osdu.corelibazure.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> - <!-- - Override the spring-boot version of these dependencies to the ones - required by the azure-core library. This needs to be done for each - app that depends on this library - --> - <dependency> - <groupId>io.projectreactor.netty</groupId> - <artifactId>reactor-netty</artifactId> - <version>${reactor.netty.version}</version> - </dependency> + <dependencies> + <!-- OSDU Dependencies --> + <dependency> + <groupId>org.opengroup.osdu</groupId> + <artifactId>notification-core</artifactId> + <version>${osdu.notification-core.version}</version> + </dependency> + <dependency> + <groupId>org.opengroup.osdu</groupId> + <artifactId>os-core-common</artifactId> + </dependency> + <dependency> + <groupId>org.opengroup.osdu</groupId> + <artifactId>core-lib-azure</artifactId> + <version>${osdu.corelibazure.version}</version> + </dependency> - <dependency> - <groupId>io.projectreactor</groupId> - <artifactId>reactor-core</artifactId> - <version>${reactor.core.version}</version> - </dependency> + <!-- Spring Dependencies --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + <exclusions> + <exclusion> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + </exclusion> + <exclusion> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-to-slf4j</artifactId> + </exclusion> + </exclusions> + </dependency> - <!-- Test Dependencies --> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-test</artifactId> - <scope>test</scope> - <exclusions> - <exclusion> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-logging</artifactId> - </exclusion> - </exclusions> - <version>2.1.6.RELEASE</version> - </dependency> - <dependency> - <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter</artifactId> - <version>5.6.0</version> - <scope>test</scope> - </dependency> + <!-- Azure Dependencies --> + <dependency> + <groupId>com.microsoft.azure</groupId> + <artifactId>azure-active-directory-spring-boot-starter</artifactId> + </dependency> - <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-junit-jupiter</artifactId> - <version>2.23.0</version> - <scope>test</scope> - </dependency> - </dependencies> + <!-- Test Dependencies --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-logging</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-junit-jupiter</artifactId> + <version>${mockito.version}</version> + <scope>test</scope> + </dependency> + </dependencies> - <build> - <plugins> - <plugin> - <groupId>org.jacoco</groupId> - <artifactId>jacoco-maven-plugin</artifactId> - <version>0.8.2</version> - <executions> - <execution> - <goals> - <goal>prepare-agent</goal> - </goals> - </execution> - <execution> - <id>report</id> - <phase>prepare-package</phase> - <goals> - <goal>report</goal> - </goals> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-maven-plugin</artifactId> - <executions> - <execution> - <goals> - <goal>repackage</goal> - </goals> - <configuration> - <classifier>spring-boot</classifier> - <mainClass> - org.opengroup.osdu.notification.provider.azure.Application - </mainClass> - </configuration> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <version>2.4.2</version> - <configuration> - <useSystemClassLoader>false</useSystemClassLoader> - <threadCount>1</threadCount> - </configuration> - </plugin> - </plugins> - </build> - <reporting> - <plugins> - <plugin> - <groupId>org.jacoco</groupId> - <artifactId>jacoco-maven-plugin</artifactId> - <reportSets> - <reportSet> - <reports> - <!-- select non-aggregate reports --> - <report>report</report> - </reports> - </reportSet> - </reportSets> - </plugin> - </plugins> - </reporting> + <build> + <plugins> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <version>${jacoco-maven-plugin.version}</version> + <executions> + <execution> + <goals> + <goal>prepare-agent</goal> + </goals> + </execution> + <execution> + <id>report</id> + <phase>prepare-package</phase> + <goals> + <goal>report</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + <configuration> + <classifier>spring-boot</classifier> + <mainClass>org.opengroup.osdu.notification.provider.azure.Application</mainClass> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.4.2</version> + <configuration> + <useSystemClassLoader>false</useSystemClassLoader> + <threadCount>1</threadCount> + </configuration> + </plugin> + </plugins> + </build> + <reporting> + <plugins> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <reportSets> + <reportSet> + <reports> + <!-- select non-aggregate reports --> + <report>report</report> + </reports> + </reportSet> + </reportSets> + </plugin> + </plugins> + </reporting> </project> \ No newline at end of file diff --git a/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/AzureCosmosProperties.java b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/AzureCosmosProperties.java index 84ba639f5..c606785da 100644 --- a/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/AzureCosmosProperties.java +++ b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/AzureCosmosProperties.java @@ -1,59 +1,30 @@ package org.opengroup.osdu.notification.provider.azure.util; -import com.azure.security.keyvault.secrets.SecretClient; -import com.azure.security.keyvault.secrets.models.KeyVaultSecret; +import javax.inject.Named; + import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.inject.Named; - @Configuration public class AzureCosmosProperties { - @Value("${tenantinfo.container.name}") - private String tenantInfoContainerName; - - @Value("${azure.cosmosdb.database}") - private String cosmosDBName; - - // TODO : Move away from Named beans. - @Bean - @Named("COSMOS_ENDPOINT") - public String cosmosEndpoint(SecretClient kv) { - return getKeyVaultSecret(kv, "opendes-cosmos-endpoint"); - } - - @Bean - @Named("COSMOS_KEY") - public String cosmosKey(SecretClient kv) { - return getKeyVaultSecret(kv, "opendes-cosmos-primary-key"); - } - - @Bean - @Named("COSMOS_CONTAINER_NAME") - public String containerName() { - return tenantInfoContainerName; - } - - @Bean - @Named("COSMOS_DB_NAME") - public String cosmosDBName() { - return cosmosDBName; - } - - private String getKeyVaultSecret(SecretClient kv, String secretName) { - KeyVaultSecret secret = kv.getSecret(secretName); - if (secret == null) { - throw new IllegalStateException(String.format("No secret found with name %s", secretName)); - } - - String secretValue = secret.getValue(); - if (secretValue == null) { - throw new IllegalStateException(String.format( - "Secret unexpectedly missing from KeyVault response for secret with name %s", secretName)); - } - - return secretValue; - } + @Value("${tenantinfo.container.name}") + private String tenantInfoContainerName; + + @Value("${azure.cosmosdb.database}") + private String cosmosDBName; + + @Bean + @Named("COSMOS_CONTAINER_NAME") + public String containerName() { + return tenantInfoContainerName; + } + + @Bean + @Named("COSMOS_DB_NAME") + public String cosmosDBName() { + return cosmosDBName; + } + } diff --git a/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/HandshakeFilter.java b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/HandshakeFilter.java index 46573ba5f..7e70bf2ec 100644 --- a/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/HandshakeFilter.java +++ b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/HandshakeFilter.java @@ -14,62 +14,75 @@ package org.opengroup.osdu.notification.provider.azure.util; -import org.opengroup.osdu.notification.provider.interfaces.IPubsubHandshakeHandler; -import org.opengroup.osdu.notification.provider.interfaces.IPubsubRequestBodyExtractor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.annotation.Order; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; +import static org.opengroup.osdu.core.common.http.ResponseHeaders.STANDARD_RESPONSE_HEADERS; -import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import java.util.Map; -import static org.opengroup.osdu.core.common.http.ResponseHeaders.STANDARD_RESPONSE_HEADERS; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.opengroup.osdu.notification.provider.interfaces.IPubsubHandshakeHandler; +import org.opengroup.osdu.notification.provider.interfaces.IPubsubRequestBodyExtractor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +/** + * TODO: logic needs to be reviewed to avoid looping dependency happening in EventGridRequestBodyExtractor for RQs + * handshake if any other filters try to inject DpsHeaders before this filter, up for now set to lowest value for + * order + */ @Component -@Order(0) +@Order(-104) public class HandshakeFilter implements Filter { - @Autowired - private IPubsubRequestBodyExtractor requestBodyExtractor; + @Autowired + private IPubsubRequestBodyExtractor requestBodyExtractor; - @Autowired - private IPubsubHandshakeHandler handshakeHandler; + @Autowired + private IPubsubHandshakeHandler handshakeHandler; - @Override - public void init(FilterConfig filterConfig) { - //do nothing - } + @Override + public void init(FilterConfig filterConfig) { + //do nothing + } - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { - HttpServletRequest request = (HttpServletRequest) servletRequest; - if(request.getServletPath().contains("records-changed") && this.requestBodyExtractor.isHandshakeRequest()){ - HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; - httpServletResponse.setStatus(200); - httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE); - setResponseHeaders(httpServletResponse); + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + if (request.getServletPath().contains("records-changed") && this.requestBodyExtractor.isHandshakeRequest()) { + HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; + httpServletResponse.setStatus(200); + httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE); + setResponseHeaders(httpServletResponse); - String handshakeResponse = this.handshakeHandler.getHandshakeResponse(); - PrintWriter out = httpServletResponse.getWriter(); - out.flush(); - out.print(handshakeResponse); - return; - } - filterChain.doFilter(servletRequest, servletResponse); + String handshakeResponse = this.handshakeHandler.getHandshakeResponse(); + PrintWriter out = httpServletResponse.getWriter(); + out.flush(); + out.print(handshakeResponse); + return; } + filterChain.doFilter(servletRequest, servletResponse); + } - @Override - public void destroy() { } + @Override + public void destroy() { + } - private void setResponseHeaders(HttpServletResponse httpServletResponse) { - for (Map.Entry<String, List<Object>> header : STANDARD_RESPONSE_HEADERS.entrySet()) { - httpServletResponse.addHeader(header.getKey(), header.getValue().toString()); - } + private void setResponseHeaders(HttpServletResponse httpServletResponse) { + for (Map.Entry<String, List<Object>> header : STANDARD_RESPONSE_HEADERS.entrySet()) { + httpServletResponse.addHeader(header.getKey(), header.getValue().toString()); } + } } diff --git a/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/Slf4jMDCFilter.java b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/Slf4jMDCFilter.java new file mode 100644 index 000000000..97c62bf56 --- /dev/null +++ b/provider/notification-azure/src/main/java/org/opengroup/osdu/notification/provider/azure/util/Slf4jMDCFilter.java @@ -0,0 +1,77 @@ +package org.opengroup.osdu.notification.provider.azure.util; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import org.opengroup.osdu.azure.util.AuthUtils; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import com.nimbusds.jwt.JWTClaimsSet; + +/** + * NOTE: should be removed after rewriting HandshakeFilter and revert logging.mdccontext.enabled=true, Order of calling + * the filters becomes: OrderedRequestContextFilter --> HandshakeFilter --> MDC filter --> ... --> TransactionLogFilter + */ +@Component +@Order(-103) +public class Slf4jMDCFilter implements Filter { + + @Autowired + private DpsHeaders dpsHeaders; + @Autowired + private AuthUtils authUtils; + + /** + * Filter logic. + * + * @param servletRequest Request object. + * @param servletResponse Response object. + * @param filterChain Filter Chain object. + */ + @Override + public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, + final FilterChain filterChain) throws IOException, ServletException { + MDC.clear(); + MDC.setContextMap(getContextMap()); + filterChain.doFilter(servletRequest, servletResponse); + } + + /** + * Method to create context map for mdc. + * + * @return Context map. + */ + private Map<String, String> getContextMap() { + final Map<String, String> contextMap = new HashMap<>(); + contextMap.put(DpsHeaders.CORRELATION_ID, dpsHeaders.getCorrelationId()); + contextMap.put(DpsHeaders.DATA_PARTITION_ID, dpsHeaders.getPartitionId()); + + String userId = getUserId(); + if (userId != null) { + contextMap.put("user-id", userId); + } + + return contextMap; + } + + /** + * Get user ID from Authorization payload (JWT token). + * + * @return the user ID + */ + private String getUserId() { + JWTClaimsSet claimsSet = authUtils.getClaimsFromJwtToken(dpsHeaders.getAuthorization()); + return claimsSet == null ? null : claimsSet.getSubject(); + } +} diff --git a/provider/notification-azure/src/main/resources/application.properties b/provider/notification-azure/src/main/resources/application.properties index 9f40a8344..3864e3180 100644 --- a/provider/notification-azure/src/main/resources/application.properties +++ b/provider/notification-azure/src/main/resources/application.properties @@ -12,21 +12,32 @@ # See the License for the specific language governing permissions and # limitations under the License. -server.servlet.context-path=/api/notification/v1 -app.expireTime=300 -app.maxCacheSize=10 +# Application +spring.application.name=${spring_application_name} +server.port=${server_port} +server.servlet.context-path=${server.servlet.contextPath} server.error.whitelabel.enabled=false +# Logging configuration +LOG_PREFIX=${LOG_PREFIX} +logging.level.org.springframework.web=DEBUG +logging.transaction.enabled=true +logging.slf4jlogger.enabled=true +logging.mdccontext.enabled=false + # Service settings +PARTITION_API=${partition_service_endpoint} app.entitlements=${entitlements_service_endpoint} app.register=${registeration_service_endpoint} app.project=opendes -server.port=8080 +app.expireTime=300 +app.maxCacheSize=10 # Azure AD configuration azure.activedirectory.client-id=${aad_client_id} azure.activedirectory.AppIdUri=api://${azure.activedirectory.client-id} azure.activedirectory.session-stateless=true +azure.activedirectory.app-resource-id=${aad_client_id} aad.oboApi=${aad_client_id} azure.application-insights.instrumentation-key=${appinsights_key} @@ -34,17 +45,10 @@ aad.eventGridId=4962773b-9cdb-44cf-a8bf-237846a00ab7 # Azure CosmosDB configuration azure.cosmosdb.database=${cosmosdb_database} -tenantInfo.container.name=TenantInfo # Azure KeyVault configuration azure.keyvault.url=${KEYVAULT_URI} -# Application name -spring.application.name=notification-azure - -# Logging configuration -logging.level.org.springframework.web=DEBUG -LOG_PREFIX=notification -logging.transaction.enabled=true -logging.slf4jlogger.enabled=true -logging.mdccontext.enabled=true \ No newline at end of file +#TenantFactory Configuration +tenantFactoryImpl.required=true +tenantInfo.container.name=TenantInfo \ No newline at end of file diff --git a/provider/notification-azure/src/test/java/org/opengroup/osdu/notification/util/AzureCosmosPropertiesTest.java b/provider/notification-azure/src/test/java/org/opengroup/osdu/notification/util/AzureCosmosPropertiesTest.java deleted file mode 100644 index 0bc49cd9a..000000000 --- a/provider/notification-azure/src/test/java/org/opengroup/osdu/notification/util/AzureCosmosPropertiesTest.java +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright © Microsoft Corporation -// -// 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 org.opengroup.osdu.notification.util; - -import com.azure.security.keyvault.secrets.SecretClient; -import com.azure.security.keyvault.secrets.models.KeyVaultSecret; -import org.junit.Before; -import org.junit.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.opengroup.osdu.notification.provider.azure.util.AzureCosmosProperties; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.doReturn; -import static org.mockito.MockitoAnnotations.initMocks; - -public class AzureCosmosPropertiesTest { - - @InjectMocks - private AzureCosmosProperties sut; - - @Mock - private SecretClient kv; - - @Mock - private KeyVaultSecret secret; - - @Before - public void init() { - initMocks(this); - } - - @Test - public void should_throwWhenSecretNameIsNull_getKeyVaultSecret() { - // Set-Up - doReturn(null).when(kv).getSecret("secret-name"); - - // Act - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> sut.cosmosKey(kv)); - - // Assert - assertEquals("No secret found with name opendes-cosmos-primary-key", exception.getMessage()); - } - - @Test - public void should_returnRightCosmosKey_getCosmosKey() { - // Set-Up - doReturn("cosmos-key-secret").when(secret).getValue(); - doReturn(secret).when(kv).getSecret("opendes-cosmos-primary-key"); - - // Act - String secretValue = sut.cosmosKey(kv); - - // Assert - assertEquals( "cosmos-key-secret", secretValue); - } - - @Test - public void should_returnRightCosmosSecret_getCosmosKey() { - // Set-Up - doReturn("cosmos-endpoint-secret").when(secret).getValue(); - doReturn(secret).when(kv).getSecret("opendes-cosmos-endpoint"); - - // Act - String secretValue = sut.cosmosEndpoint(kv); - - // Assert - assertEquals( "cosmos-endpoint-secret", secretValue); - } -} -- GitLab