From 2aba670ebd6cc7828ab2b389ed718dc5e44d3de8 Mon Sep 17 00:00:00 2001 From: haaggarw Date: Sun, 2 Aug 2020 05:00:58 +0000 Subject: [PATCH 01/12] Adding AzureServicePrinciple class --- pom.xml | 2 +- .../azure/multitenancy/TenantFactoryImpl.java | 120 ++++++++++++++++++ .../azure/multitenancy/TenantInfoDoc.java | 34 +++++ .../azure/util/AzureServicePrincipal.java | 106 ++++++++++++++++ src/main/resources/application.properties | 19 +++ 5 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java create mode 100644 src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java create mode 100644 src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java create mode 100644 src/main/resources/application.properties diff --git a/pom.xml b/pom.xml index 4e8ae794..ee957547 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ org.opengroup.osdu core-lib-azure jar - 0.0.13 + 0.0.14 core-lib-azure diff --git a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java new file mode 100644 index 00000000..ebe5c3ef --- /dev/null +++ b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java @@ -0,0 +1,120 @@ +// 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.azure.multitenancy; + +import org.opengroup.osdu.azure.CosmosStore; +import org.opengroup.osdu.core.common.cache.ICache; +import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory; +import org.opengroup.osdu.core.common.model.tenant.TenantInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import java.util.Map; +import java.util.HashMap; +import java.util.Collection; + +/** + * Implementation for ITenantFactory. + */ +@Component +@Lazy +public class TenantFactoryImpl implements ITenantFactory { + + @Value("${tenantInfo.container.name}") + private String tenantInfoContainer; + + @Value("${azure.cosmosdb.database}") + private String cosmosDBName; + + @Autowired + @Lazy + private CosmosStore cosmosStore; + + private Map tenants; + + /** + * @param tenantName Tenant name + * @return true or false depending on whether tenant is present + */ + public boolean exists(final String tenantName) { + if (this.tenants == null) { + initTenants(); + } + return this.tenants.containsKey(tenantName); + } + + /** + * @param tenantName Tenant name + * @return tenantInfo object + */ + public TenantInfo getTenantInfo(final String tenantName) { + if (this.tenants == null) { + initTenants(); + } + return this.tenants.get(tenantName); + } + + /** + * @return list of tenantInfo objects for all the tenants + */ + public Collection listTenantInfo() { + if (this.tenants == null) { + initTenants(); + } + return this.tenants.values(); + } + + /** + * @param tenantName Tenant name + * @param host Host name + * @param port Port + * @param expireTimeSeconds Expiry time in seconds + * @param classOfV Class reference + * @param Template class + * @return cache + */ + public ICache createCache(final String tenantName, final String host, final int port, final int expireTimeSeconds, final Class classOfV) { + return null; + } + + + /** + * Flush the cache. + */ + public void flushCache() { + + } + + /** + * Initialise the local cache for tenants. + */ + private void initTenants() { + this.tenants = new HashMap<>(); + + // TODO partition id should not be required because tenant details will be kept in a known partition + String dataPartitionId = "data-partition-id"; + + cosmosStore.findAllItems(dataPartitionId, cosmosDBName, tenantInfoContainer, TenantInfoDoc.class).forEach( + tenantInfoDoc -> { + TenantInfo ti = new TenantInfo(); + String tenantName = tenantInfoDoc.getId(); + ti.setName(tenantName); + this.tenants.put(tenantName, ti); + } + ); + } +} \ No newline at end of file diff --git a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java new file mode 100644 index 00000000..0d996224 --- /dev/null +++ b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java @@ -0,0 +1,34 @@ +// 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.azure.multitenancy; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * TenantInfoDoc class. + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Getter +public class TenantInfoDoc { + private String id; + private List groups; +} diff --git a/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java b/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java new file mode 100644 index 00000000..11b4d909 --- /dev/null +++ b/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java @@ -0,0 +1,106 @@ +// 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.azure.util; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; + +/** + * Class to generate the AAD authentication tokens. + */ +public final class AzureServicePrincipal { + + /** + * Private constructor -- this class should never be instantiated. + */ + private AzureServicePrincipal() { + } + + /** + * @param sp_id AZURE CLIENT ID + * @param sp_secret AZURE CLIENT SECRET + * @param tenant_id AZURE TENANT ID + * @param app_resource_id AZURE APP RESOURCE ID + * @return AUTHENTICATION TOKEN + * @throws Exception throws exception + */ + public static String getIdToken(final String sp_id, final String sp_secret, final String tenant_id, final String app_resource_id) throws Exception { + String aadEndpoint = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenant_id); + URL url = new URL(aadEndpoint); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + + Map parameters = new HashMap<>(); + parameters.put("grant_type", "client_credentials"); + parameters.put("client_id", sp_id); + parameters.put("client_secret", sp_secret); + parameters.put("resource", app_resource_id); + + con.setDoOutput(true); + DataOutputStream out = new DataOutputStream(con.getOutputStream()); + out.writeBytes(getParamsString(parameters)); + out.flush(); + out.close(); + + BufferedReader in = new BufferedReader( + new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer content = new StringBuffer(); + while ((inputLine = in.readLine()) != null) { + content.append(inputLine); + } + in.close(); + + con.disconnect(); + + Gson gson = new Gson(); + JsonObject jobj = gson.fromJson(content.toString(), JsonObject.class); + String token = jobj.get("access_token").getAsString(); + return token; + } + + /** + * @param params Map of request parameters + * @return parameter string + * @throws UnsupportedEncodingException throws exception unsupported encoding is found + */ + private static String getParamsString(final Map params) + throws UnsupportedEncodingException { + StringBuilder result = new StringBuilder(); + + for (Map.Entry entry : params.entrySet()) { + result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); + result.append("="); + result.append(URLEncoder.encode(entry.getValue(), "UTF-8")); + result.append("&"); + } + + String resultString = result.toString(); + return resultString.length() > 0 + ? resultString.substring(0, resultString.length() - 1) + : resultString; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 00000000..d817f227 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,19 @@ +# +# 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. +# + +# Azure CosmosDB configuration +tenantInfo.container.name=TenantInfo +azure.cosmosdb.database=${cosmosdb_database} \ No newline at end of file -- GitLab From 1f71eed913f350019d69ad44e5ab5c86c0ef1c5d Mon Sep 17 00:00:00 2001 From: haaggarw Date: Tue, 4 Aug 2020 06:54:29 +0000 Subject: [PATCH 02/12] Addressing PR comments --- .../osdu/azure/di/CosmosDBConfiguration.java | 37 +++++++++++++++++++ .../azure/multitenancy/TenantFactoryImpl.java | 10 +++-- 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/opengroup/osdu/azure/di/CosmosDBConfiguration.java diff --git a/src/main/java/org/opengroup/osdu/azure/di/CosmosDBConfiguration.java b/src/main/java/org/opengroup/osdu/azure/di/CosmosDBConfiguration.java new file mode 100644 index 00000000..1c13a2b0 --- /dev/null +++ b/src/main/java/org/opengroup/osdu/azure/di/CosmosDBConfiguration.java @@ -0,0 +1,37 @@ +package org.opengroup.osdu.azure.di; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import javax.inject.Named; + +/** + * A configuration bean class to set up CosmosDb variables. + */ +@Configuration +public class CosmosDBConfiguration { + + @Value("${tenantInfo.container.name}") + private String tenantInfoContainer; + + @Value("${azure.cosmosdb.database}") + private String cosmosDBName; + + /** + * @return name of the Cosmos db collection for all the tenants + */ + @Bean + @Named("TenantInfoContainer") + public String getTenantInfoContainer() { + return tenantInfoContainer; + } + + /** + * @return name od the Cosmos db database + */ + @Bean + @Named("CosmosDatabaseName") + public String getCosmosDBName() { + return cosmosDBName; + } +} diff --git a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java index ebe5c3ef..4558374c 100644 --- a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java +++ b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java @@ -19,7 +19,7 @@ import org.opengroup.osdu.core.common.cache.ICache; import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory; import org.opengroup.osdu.core.common.model.tenant.TenantInfo; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @@ -34,10 +34,14 @@ import java.util.Collection; @Lazy public class TenantFactoryImpl implements ITenantFactory { - @Value("${tenantInfo.container.name}") + @Autowired + @Qualifier("TenantInfoContainer") + @Lazy private String tenantInfoContainer; - @Value("${azure.cosmosdb.database}") + @Autowired + @Qualifier("CosmosDatabaseName") + @Lazy private String cosmosDBName; @Autowired -- GitLab From 0a722678a9065b62a24c66396a9b56b6690a7283 Mon Sep 17 00:00:00 2001 From: haaggarw Date: Wed, 5 Aug 2020 08:26:53 +0000 Subject: [PATCH 03/12] Addressing PR comments --- .../osdu/azure/di/CosmosDBConfiguration.java | 21 +--- .../azure/multitenancy/TenantFactoryImpl.java | 15 +-- .../azure/multitenancy/TenantInfoDoc.java | 5 - .../azure/util/AzureServicePrincipal.java | 49 +++++--- .../multitenancy/TenantFactoryImplTest.java | 107 ++++++++++++++++++ .../azure/util/AzureServicePrincipalTest.java | 92 +++++++++++++++ 6 files changed, 241 insertions(+), 48 deletions(-) create mode 100644 src/test/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImplTest.java create mode 100644 src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java diff --git a/src/main/java/org/opengroup/osdu/azure/di/CosmosDBConfiguration.java b/src/main/java/org/opengroup/osdu/azure/di/CosmosDBConfiguration.java index 1c13a2b0..1f90097f 100644 --- a/src/main/java/org/opengroup/osdu/azure/di/CosmosDBConfiguration.java +++ b/src/main/java/org/opengroup/osdu/azure/di/CosmosDBConfiguration.java @@ -1,14 +1,14 @@ package org.opengroup.osdu.azure.di; +import lombok.Getter; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.inject.Named; /** * A configuration bean class to set up CosmosDb variables. */ @Configuration +@Getter public class CosmosDBConfiguration { @Value("${tenantInfo.container.name}") @@ -17,21 +17,4 @@ public class CosmosDBConfiguration { @Value("${azure.cosmosdb.database}") private String cosmosDBName; - /** - * @return name of the Cosmos db collection for all the tenants - */ - @Bean - @Named("TenantInfoContainer") - public String getTenantInfoContainer() { - return tenantInfoContainer; - } - - /** - * @return name od the Cosmos db database - */ - @Bean - @Named("CosmosDatabaseName") - public String getCosmosDBName() { - return cosmosDBName; - } } diff --git a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java index 4558374c..34e04d9d 100644 --- a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java +++ b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java @@ -15,11 +15,12 @@ package org.opengroup.osdu.azure.multitenancy; import org.opengroup.osdu.azure.CosmosStore; +import org.opengroup.osdu.azure.di.CosmosDBConfiguration; import org.opengroup.osdu.core.common.cache.ICache; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory; import org.opengroup.osdu.core.common.model.tenant.TenantInfo; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @@ -35,14 +36,8 @@ import java.util.Collection; public class TenantFactoryImpl implements ITenantFactory { @Autowired - @Qualifier("TenantInfoContainer") @Lazy - private String tenantInfoContainer; - - @Autowired - @Qualifier("CosmosDatabaseName") - @Lazy - private String cosmosDBName; + private CosmosDBConfiguration cosmosDBConfiguration; @Autowired @Lazy @@ -110,9 +105,7 @@ public class TenantFactoryImpl implements ITenantFactory { this.tenants = new HashMap<>(); // TODO partition id should not be required because tenant details will be kept in a known partition - String dataPartitionId = "data-partition-id"; - - cosmosStore.findAllItems(dataPartitionId, cosmosDBName, tenantInfoContainer, TenantInfoDoc.class).forEach( + cosmosStore.findAllItems(DpsHeaders.DATA_PARTITION_ID, cosmosDBConfiguration.getCosmosDBName(), cosmosDBConfiguration.getTenantInfoContainer(), TenantInfoDoc.class).forEach( tenantInfoDoc -> { TenantInfo ti = new TenantInfo(); String tenantName = tenantInfoDoc.getId(); diff --git a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java index 0d996224..7c2f72d5 100644 --- a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java +++ b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java @@ -17,18 +17,13 @@ package org.opengroup.osdu.azure.multitenancy; import lombok.AllArgsConstructor; import lombok.Data; import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.util.List; /** * TenantInfoDoc class. */ @Data @AllArgsConstructor -@NoArgsConstructor @Getter public class TenantInfoDoc { private String id; - private List groups; } diff --git a/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java b/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java index 11b4d909..7275ca13 100644 --- a/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java +++ b/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java @@ -19,6 +19,7 @@ import com.google.gson.JsonObject; import java.io.BufferedReader; import java.io.DataOutputStream; +import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; @@ -32,23 +33,45 @@ import java.util.Map; */ public final class AzureServicePrincipal { + private Gson gsonTest; + private URL urlTest; + private DataOutputStream dataOutputStreamTest; + private BufferedReader bufferedReaderTest; + private InputStreamReader inputStreamReaderTest; + /** - * Private constructor -- this class should never be instantiated. + * public constructor. */ - private AzureServicePrincipal() { + public AzureServicePrincipal() { + } + /** Parametrised constructor for testing purposes. + * @param gson Gson object for testing purposes + * @param url url object for testing purposes + * @param dataOutputStream dataOutputStream object for testing purposes + * @param bufferedReader bufferedReader object for testing purposes + * @param inputStreamReader inputStreamReader object for testing purposes + */ + public AzureServicePrincipal(final Gson gson, final URL url, final DataOutputStream dataOutputStream, final BufferedReader bufferedReader, final InputStreamReader inputStreamReader) { + this.gsonTest = gson; + this.urlTest = url; + this.dataOutputStreamTest = dataOutputStream; + this.bufferedReaderTest = bufferedReader; + this.inputStreamReaderTest = inputStreamReader; + } /** * @param sp_id AZURE CLIENT ID * @param sp_secret AZURE CLIENT SECRET * @param tenant_id AZURE TENANT ID * @param app_resource_id AZURE APP RESOURCE ID * @return AUTHENTICATION TOKEN - * @throws Exception throws exception + * @throws IOException throws IO exception */ - public static String getIdToken(final String sp_id, final String sp_secret, final String tenant_id, final String app_resource_id) throws Exception { + public String getIdToken(final String sp_id, final String sp_secret, final String tenant_id, final String app_resource_id) throws IOException { + String aadEndpoint = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenant_id); - URL url = new URL(aadEndpoint); + URL url = urlTest != null ? urlTest : new URL(aadEndpoint); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); @@ -60,15 +83,16 @@ public final class AzureServicePrincipal { parameters.put("resource", app_resource_id); con.setDoOutput(true); - DataOutputStream out = new DataOutputStream(con.getOutputStream()); + DataOutputStream out = dataOutputStreamTest != null ? dataOutputStreamTest : new DataOutputStream(con.getOutputStream()); out.writeBytes(getParamsString(parameters)); out.flush(); out.close(); - BufferedReader in = new BufferedReader( - new InputStreamReader(con.getInputStream())); + InputStreamReader inputStreamReader = inputStreamReaderTest != null ? inputStreamReaderTest : new InputStreamReader(con.getInputStream()); + + BufferedReader in = bufferedReaderTest != null ? bufferedReaderTest : new BufferedReader(inputStreamReader); String inputLine; - StringBuffer content = new StringBuffer(); + StringBuilder content = new StringBuilder(); while ((inputLine = in.readLine()) != null) { content.append(inputLine); } @@ -76,10 +100,9 @@ public final class AzureServicePrincipal { con.disconnect(); - Gson gson = new Gson(); - JsonObject jobj = gson.fromJson(content.toString(), JsonObject.class); - String token = jobj.get("access_token").getAsString(); - return token; + Gson gson = gsonTest != null ? gsonTest : new Gson(); + JsonObject jsonObject = gson.fromJson(content.toString(), JsonObject.class); + return jsonObject.get("access_token").getAsString(); } /** diff --git a/src/test/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImplTest.java b/src/test/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImplTest.java new file mode 100644 index 00000000..345ec8e5 --- /dev/null +++ b/src/test/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImplTest.java @@ -0,0 +1,107 @@ +package org.opengroup.osdu.azure.multitenancy; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.when; +import org.opengroup.osdu.azure.CosmosStore; +import org.opengroup.osdu.azure.di.CosmosDBConfiguration; +import org.opengroup.osdu.core.common.model.tenant.TenantInfo; + +@ExtendWith(MockitoExtension.class) +public class TenantFactoryImplTest { + + private static final String tenantName = "opendes"; + private static final String cosmosDatabase = "cosmos-database"; + private static final String cosmosContainer = "tenant-info"; + private static final String notFound = "not-found"; + + @InjectMocks + private TenantFactoryImpl tenantFactory; + + @Mock + private CosmosDBConfiguration cosmosDBConfiguration; + + @Mock + private CosmosStore cosmosStore; + + @BeforeEach + public void init() { + when(cosmosDBConfiguration.getCosmosDBName()).thenReturn(cosmosDatabase); + when(cosmosDBConfiguration.getTenantInfoContainer()).thenReturn(cosmosContainer); + } + + @Test + public void returnsTrueWhenTenantNameFound() { + TenantInfoDoc doc = new TenantInfoDoc(tenantName); + + doReturn(Collections.singletonList(doc)).when(cosmosStore).findAllItems(eq(DpsHeaders.DATA_PARTITION_ID), eq(cosmosDatabase), eq(cosmosContainer), any()); + boolean result = tenantFactory.exists(tenantName); + + assertTrue(result); + } + + @Test + public void returnsFalseWhenTenantNameNotFound() { + TenantInfoDoc doc = new TenantInfoDoc(tenantName + notFound); + + doReturn(Collections.singletonList(doc)).when(cosmosStore).findAllItems(eq(DpsHeaders.DATA_PARTITION_ID), eq(cosmosDatabase), eq(cosmosContainer), any()); + boolean result = tenantFactory.exists(tenantName); + + assertFalse(result); + } + + @Test + public void returnsTenantInfoObjectWhenTenantNameFound() { + TenantInfoDoc doc = new TenantInfoDoc(tenantName); + + doReturn(Collections.singletonList(doc)).when(cosmosStore).findAllItems(eq(DpsHeaders.DATA_PARTITION_ID), eq(cosmosDatabase), eq(cosmosContainer), any()); + TenantInfo result = tenantFactory.getTenantInfo(tenantName); + + TenantInfo expected = new TenantInfo(); + expected.setName(tenantName); + + assertEquals(expected, result); + } + + @Test + public void returnsNullWhenTenantNameNotFound() { + TenantInfoDoc doc = new TenantInfoDoc(tenantName + notFound); + + doReturn(Collections.singletonList(doc)).when(cosmosStore).findAllItems(eq(DpsHeaders.DATA_PARTITION_ID), eq(cosmosDatabase), eq(cosmosContainer), any()); + TenantInfo result = tenantFactory.getTenantInfo(tenantName); + + assertNull(result); + } + + @Test + public void returnsListOfAllTenants() { + TenantInfoDoc doc = new TenantInfoDoc(tenantName); + + doReturn(Collections.singletonList(doc)).when(cosmosStore).findAllItems(eq(DpsHeaders.DATA_PARTITION_ID), eq(cosmosDatabase), eq(cosmosContainer), any()); + List result = new ArrayList<>(tenantFactory.listTenantInfo()); + + TenantInfo tenantInfo = new TenantInfo(); + tenantInfo.setName(tenantName); + + List expected = Collections.singletonList(tenantInfo); + + assertEquals(expected, result); + } +} diff --git a/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java b/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java new file mode 100644 index 00000000..179191e6 --- /dev/null +++ b/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java @@ -0,0 +1,92 @@ +package org.opengroup.osdu.azure.util; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class AzureServicePrincipalTest { + + private static final String paramsString = "grant_type=client_credentials&resource=app-resource-id&client_secret=client-secret&client_id=client-id"; + private static final String accessToken = "some-access-token"; + private static final String content = "some-content"; + private static final String spId = "client-id"; + private static final String spSecret = "client-secret"; + private static final String tenantId = "tenant-id"; + private static final String appResourceId = "app-resource-id"; + + @Mock + private Gson gson; + + @Mock + private URL url; + + @Mock + private DataOutputStream dataOutputStream; + + @Mock + private BufferedReader bufferedReader; + + @Mock + private InputStreamReader inputStreamReader; + + @Mock + private HttpURLConnection httpURLConnection; + + @Test + public void ShouldSuccessfullyGenerateToken() throws Exception { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("access_token", accessToken); + + when(url.openConnection()).thenReturn(httpURLConnection); + when(bufferedReader.readLine()).thenReturn(content).thenReturn(null); + when(gson.fromJson(content, JsonObject.class)).thenReturn(jsonObject); + + AzureServicePrincipal azureServicePrincipal = new AzureServicePrincipal(gson, url, dataOutputStream, bufferedReader, inputStreamReader); + + String result = azureServicePrincipal.getIdToken(spId, spSecret, tenantId, appResourceId); + + assertEquals(accessToken, result); + verify(httpURLConnection, times(1)).setRequestMethod("POST"); + verify(httpURLConnection, times(1)).setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + verify(httpURLConnection, times(1)).setDoOutput(true); + verify(dataOutputStream, times(1)).writeBytes(paramsString); + verify(dataOutputStream, times(1)).flush(); + verify(dataOutputStream, times(1)).close(); + verify(bufferedReader, times(2)).readLine(); + verify(bufferedReader, times(1)).close(); + verify(httpURLConnection, times(1)).disconnect(); + verify(gson, times(1)).fromJson(content, JsonObject.class); + } + + @Test + public void ShouldThrowIOException() throws Exception { + + when(url.openConnection()).thenThrow(IOException.class); + + AzureServicePrincipal azureServicePrincipal = new AzureServicePrincipal(gson, url, dataOutputStream, bufferedReader, inputStreamReader); + + IOException exception = assertThrows(IOException.class, () -> { + azureServicePrincipal.getIdToken(spId, spSecret, tenantId, appResourceId); + }); + + assertNotNull(exception); + } +} -- GitLab From 6e0c88d168e87b3a3ceaa64cb4cd46ec78623771 Mon Sep 17 00:00:00 2001 From: haaggarw Date: Wed, 5 Aug 2020 08:29:26 +0000 Subject: [PATCH 04/12] Upgrading pom.xml to v0.0.16 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aeecd6fd..ed1aae4c 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ org.opengroup.osdu core-lib-azure jar - 0.0.15 + 0.0.16 core-lib-azure -- GitLab From 9aab4e489de6c47f3efe102a045b83f9d3808dc6 Mon Sep 17 00:00:00 2001 From: haaggarw Date: Wed, 5 Aug 2020 14:17:47 +0000 Subject: [PATCH 05/12] Replacing url connection with httpclient --- .../azure/util/AzureServicePrincipal.java | 83 ++++++------------- .../azure/util/AzureServicePrincipalTest.java | 68 ++++----------- 2 files changed, 42 insertions(+), 109 deletions(-) diff --git a/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java b/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java index 7275ca13..709cdc14 100644 --- a/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java +++ b/src/main/java/org/opengroup/osdu/azure/util/AzureServicePrincipal.java @@ -14,94 +14,52 @@ package org.opengroup.osdu.azure.util; +import com.azure.core.http.HttpClient; +import com.azure.core.http.HttpMethod; +import com.azure.core.http.HttpRequest; +import com.azure.core.http.HttpResponse; +import com.azure.core.http.netty.NettyAsyncHttpClientBuilder; import com.google.gson.Gson; import com.google.gson.JsonObject; +import reactor.core.publisher.Mono; -import java.io.BufferedReader; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; +import java.util.Objects; /** * Class to generate the AAD authentication tokens. */ public final class AzureServicePrincipal { - private Gson gsonTest; - private URL urlTest; - private DataOutputStream dataOutputStreamTest; - private BufferedReader bufferedReaderTest; - private InputStreamReader inputStreamReaderTest; - - /** - * public constructor. - */ - public AzureServicePrincipal() { - - } - - /** Parametrised constructor for testing purposes. - * @param gson Gson object for testing purposes - * @param url url object for testing purposes - * @param dataOutputStream dataOutputStream object for testing purposes - * @param bufferedReader bufferedReader object for testing purposes - * @param inputStreamReader inputStreamReader object for testing purposes - */ - public AzureServicePrincipal(final Gson gson, final URL url, final DataOutputStream dataOutputStream, final BufferedReader bufferedReader, final InputStreamReader inputStreamReader) { - this.gsonTest = gson; - this.urlTest = url; - this.dataOutputStreamTest = dataOutputStream; - this.bufferedReaderTest = bufferedReader; - this.inputStreamReaderTest = inputStreamReader; - } /** * @param sp_id AZURE CLIENT ID * @param sp_secret AZURE CLIENT SECRET * @param tenant_id AZURE TENANT ID * @param app_resource_id AZURE APP RESOURCE ID * @return AUTHENTICATION TOKEN - * @throws IOException throws IO exception + * @throws UnsupportedEncodingException throws UnsupportedEncodingException */ - public String getIdToken(final String sp_id, final String sp_secret, final String tenant_id, final String app_resource_id) throws IOException { + public String getIdToken(final String sp_id, final String sp_secret, final String tenant_id, final String app_resource_id) throws UnsupportedEncodingException { String aadEndpoint = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenant_id); - URL url = urlTest != null ? urlTest : new URL(aadEndpoint); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("POST"); - con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - + HttpRequest httpRequest = new HttpRequest(HttpMethod.POST, aadEndpoint); Map parameters = new HashMap<>(); parameters.put("grant_type", "client_credentials"); parameters.put("client_id", sp_id); parameters.put("client_secret", sp_secret); parameters.put("resource", app_resource_id); + httpRequest.setBody(getParamsString(parameters)); - con.setDoOutput(true); - DataOutputStream out = dataOutputStreamTest != null ? dataOutputStreamTest : new DataOutputStream(con.getOutputStream()); - out.writeBytes(getParamsString(parameters)); - out.flush(); - out.close(); - - InputStreamReader inputStreamReader = inputStreamReaderTest != null ? inputStreamReaderTest : new InputStreamReader(con.getInputStream()); - - BufferedReader in = bufferedReaderTest != null ? bufferedReaderTest : new BufferedReader(inputStreamReader); - String inputLine; - StringBuilder content = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - content.append(inputLine); - } - in.close(); + HttpClient client = createHttpClient(); - con.disconnect(); + Mono response = client.send(httpRequest); + String content = Objects.requireNonNull(response.block()).getBodyAsString().block(); - Gson gson = gsonTest != null ? gsonTest : new Gson(); - JsonObject jsonObject = gson.fromJson(content.toString(), JsonObject.class); + Gson gson = new Gson(); + JsonObject jsonObject = gson.fromJson(content, JsonObject.class); return jsonObject.get("access_token").getAsString(); } @@ -110,7 +68,7 @@ public final class AzureServicePrincipal { * @return parameter string * @throws UnsupportedEncodingException throws exception unsupported encoding is found */ - private static String getParamsString(final Map params) + private String getParamsString(final Map params) throws UnsupportedEncodingException { StringBuilder result = new StringBuilder(); @@ -126,4 +84,11 @@ public final class AzureServicePrincipal { ? resultString.substring(0, resultString.length() - 1) : resultString; } + + /** + * @return HttpClient + */ + HttpClient createHttpClient() { + return new NettyAsyncHttpClientBuilder().build(); + } } diff --git a/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java b/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java index 179191e6..805de905 100644 --- a/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java +++ b/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java @@ -1,22 +1,18 @@ package org.opengroup.osdu.azure.util; -import com.google.gson.Gson; +import com.azure.core.http.HttpClient; +import com.azure.core.http.HttpRequest; +import com.azure.core.http.HttpResponse; import com.google.gson.JsonObject; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; +import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; - -import java.io.BufferedReader; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; +import reactor.core.publisher.Mono; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -24,69 +20,41 @@ import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class AzureServicePrincipalTest { - private static final String paramsString = "grant_type=client_credentials&resource=app-resource-id&client_secret=client-secret&client_id=client-id"; private static final String accessToken = "some-access-token"; - private static final String content = "some-content"; private static final String spId = "client-id"; private static final String spSecret = "client-secret"; private static final String tenantId = "tenant-id"; private static final String appResourceId = "app-resource-id"; @Mock - private Gson gson; - - @Mock - private URL url; + private HttpClient httpClient; @Mock - private DataOutputStream dataOutputStream; + private Mono responseMono; @Mock - private BufferedReader bufferedReader; + private HttpResponse httpResponse; - @Mock - private InputStreamReader inputStreamReader; - - @Mock - private HttpURLConnection httpURLConnection; + @Spy + private AzureServicePrincipal azureServicePrincipal; @Test public void ShouldSuccessfullyGenerateToken() throws Exception { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("access_token", accessToken); - when(url.openConnection()).thenReturn(httpURLConnection); - when(bufferedReader.readLine()).thenReturn(content).thenReturn(null); - when(gson.fromJson(content, JsonObject.class)).thenReturn(jsonObject); + Mono contentMono = Mono.just(jsonObject.toString()); - AzureServicePrincipal azureServicePrincipal = new AzureServicePrincipal(gson, url, dataOutputStream, bufferedReader, inputStreamReader); + when(azureServicePrincipal.createHttpClient()).thenReturn(httpClient); + when(httpClient.send(any(HttpRequest.class))).thenReturn(responseMono); + when(responseMono.block()).thenReturn(httpResponse); + when(httpResponse.getBodyAsString()).thenReturn(contentMono); String result = azureServicePrincipal.getIdToken(spId, spSecret, tenantId, appResourceId); assertEquals(accessToken, result); - verify(httpURLConnection, times(1)).setRequestMethod("POST"); - verify(httpURLConnection, times(1)).setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - verify(httpURLConnection, times(1)).setDoOutput(true); - verify(dataOutputStream, times(1)).writeBytes(paramsString); - verify(dataOutputStream, times(1)).flush(); - verify(dataOutputStream, times(1)).close(); - verify(bufferedReader, times(2)).readLine(); - verify(bufferedReader, times(1)).close(); - verify(httpURLConnection, times(1)).disconnect(); - verify(gson, times(1)).fromJson(content, JsonObject.class); - } - - @Test - public void ShouldThrowIOException() throws Exception { - - when(url.openConnection()).thenThrow(IOException.class); - - AzureServicePrincipal azureServicePrincipal = new AzureServicePrincipal(gson, url, dataOutputStream, bufferedReader, inputStreamReader); - - IOException exception = assertThrows(IOException.class, () -> { - azureServicePrincipal.getIdToken(spId, spSecret, tenantId, appResourceId); - }); + verify(responseMono, times(1)).block(); + verify(httpResponse, times(1)).getBodyAsString(); - assertNotNull(exception); } } -- GitLab From 118bda46240ec3debf51bc371cdb4c0bd54653ee Mon Sep 17 00:00:00 2001 From: haaggarw Date: Wed, 5 Aug 2020 14:33:46 +0000 Subject: [PATCH 06/12] Upgrading to v0.0.17 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ed1aae4c..534198f9 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ org.opengroup.osdu core-lib-azure jar - 0.0.16 + 0.0.17 core-lib-azure -- GitLab From 065ea3ffbb25f7917b4924982ac83d68fc0485a9 Mon Sep 17 00:00:00 2001 From: haaggarw Date: Wed, 5 Aug 2020 18:07:37 +0000 Subject: [PATCH 07/12] Pr comments --- pom.xml | 12 ++++++++++++ .../azure/util/AzureServicePrincipalTest.java | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/pom.xml b/pom.xml index 534198f9..e858a528 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,12 @@ + + com.azure + azure-core-http-netty + 1.5.3 + + org.springframework @@ -159,6 +165,12 @@ ${jackson.version} test + + junit + junit + 4.9 + test + diff --git a/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java b/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java index 805de905..98c4f66e 100644 --- a/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java +++ b/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java @@ -4,6 +4,7 @@ import com.azure.core.http.HttpClient; import com.azure.core.http.HttpRequest; import com.azure.core.http.HttpResponse; import com.google.gson.JsonObject; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -57,4 +58,21 @@ public class AzureServicePrincipalTest { verify(httpResponse, times(1)).getBodyAsString(); } + + /** + * This test is added for end to verification whether tokens are getting generated. + */ + // + @Disabled + @Test + public void VerifyingEndToEndScenario() throws Exception { + + String spId = ""; + String spSecret = ""; + String tenantId = ""; + String appResourceId = ""; + + String result = new AzureServicePrincipal().getIdToken(spId, spSecret, tenantId, appResourceId); + + } } -- GitLab From 6e89d0f7828538920f82a6bb447b16d7b5d98a7c Mon Sep 17 00:00:00 2001 From: Hema Vishnu Pola Date: Thu, 6 Aug 2020 07:25:56 +0530 Subject: [PATCH 08/12] updated pom to resolved slf4j binding conflicts. --- pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pom.xml b/pom.xml index e858a528..e44f921a 100644 --- a/pom.xml +++ b/pom.xml @@ -86,6 +86,16 @@ org.opengroup.osdu os-core-common 0.3.4 + + + org.springframework.boot + spring-boot-starter-logging + + + org.apache.logging.log4j + log4j-api + + -- GitLab From 16a637a551d7005f718d8207ba40a61811baf142 Mon Sep 17 00:00:00 2001 From: haaggarw Date: Thu, 6 Aug 2020 03:16:50 +0000 Subject: [PATCH 09/12] Adding one more verify check in tests --- .../org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java b/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java index 98c4f66e..53d90545 100644 --- a/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java +++ b/src/test/java/org/opengroup/osdu/azure/util/AzureServicePrincipalTest.java @@ -54,6 +54,7 @@ public class AzureServicePrincipalTest { String result = azureServicePrincipal.getIdToken(spId, spSecret, tenantId, appResourceId); assertEquals(accessToken, result); + verify(httpClient, times(1)).send(any(HttpRequest.class)); verify(responseMono, times(1)).block(); verify(httpResponse, times(1)).getBodyAsString(); -- GitLab From 15a39104a6254b5d791bf2fb9385357f722a2e2e Mon Sep 17 00:00:00 2001 From: haaggarw Date: Thu, 6 Aug 2020 04:11:18 +0000 Subject: [PATCH 10/12] Removing junit dependency --- pom.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pom.xml b/pom.xml index e44f921a..c4e11784 100644 --- a/pom.xml +++ b/pom.xml @@ -175,13 +175,6 @@ ${jackson.version} test - - junit - junit - 4.9 - test - - -- GitLab From fba3ed2c3de9e15f762a73b53d16d42044d09c33 Mon Sep 17 00:00:00 2001 From: Hema Vishnu Pola Date: Thu, 6 Aug 2020 10:20:36 +0530 Subject: [PATCH 11/12] added updated NOTICE file. --- NOTICE | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/NOTICE b/NOTICE index 5196dd9e..2f780f61 100644 --- a/NOTICE +++ b/NOTICE @@ -25,7 +25,6 @@ The following software have components provided under the terms of this license: - Apache Log4j Core (from ) - Apache Log4j JUL Adapter (from ) - Apache Log4j SLF4J Binding (from ) -- Apache Log4j to SLF4J Adapter (from ) - Asynchronous Http Client (from ) - Asynchronous Http Client Netty Utils (from ) - Bean Validation API (from http://beanvalidation.org) @@ -86,6 +85,7 @@ The following software have components provided under the terms of this license: - Microsoft Application Insights Java SDK Spring Boot starter (from https://github.com/Microsoft/ApplicationInsights-Java) - Microsoft Application Insights Java SDK Web Module (from https://github.com/Microsoft/ApplicationInsights-Java) - Microsoft Application Insights Log4j 2 Appender (from https://github.com/Microsoft/ApplicationInsights-Java) +- Microsoft Azure Netty HTTP Client Library (from https://github.com/Azure/azure-sdk-for-java) - Mockito (from http://mockito.org) - Netty Reactive Streams Implementation (from ) - Netty/Buffer (from http://netty.io/) @@ -113,7 +113,6 @@ The following software have components provided under the terms of this license: - Okio (from ) - OpenCensus (from https://github.com/census-instrumentation/opencensus-java) - OpenCensus (from https://github.com/census-instrumentation/opencensus-java) -- Reactive Object Pool (from https://github.com/reactor/reactor-pool) - Reactive Streams Netty driver (from https://github.com/reactor/reactor-netty) - Retrofit (from ) - SnakeYAML (from http://www.snakeyaml.org) @@ -125,7 +124,6 @@ The following software have components provided under the terms of this license: - Spring Boot AutoConfigure (from http://projects.spring.io/spring-boot/) - Spring Boot Json Starter (from https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-starters/spring-boot-starter-json) - Spring Boot Log4J2 Starter (from http://projects.spring.io/spring-boot/) -- Spring Boot Logging Starter (from http://projects.spring.io/spring-boot/) - Spring Boot Starter (from http://projects.spring.io/spring-boot/) - Spring Boot Tomcat Starter (from http://projects.spring.io/spring-boot/) - Spring Boot Validation Starter (from http://projects.spring.io/spring-boot/) @@ -246,8 +244,6 @@ EPL-1.0 The following software have components provided under the terms of this license: - JUnit Jupiter (Aggregator) (from https://junit.org/junit5/) -- Logback Classic Module (from ) -- Logback Core Module (from ) - Microsoft Application Insights Java SDK Core (from https://github.com/Microsoft/ApplicationInsights-Java) - Microsoft Application Insights Java SDK Spring Boot starter (from https://github.com/Microsoft/ApplicationInsights-Java) - Microsoft Application Insights Java SDK Web Module (from https://github.com/Microsoft/ApplicationInsights-Java) @@ -315,8 +311,6 @@ The following software have components provided under the terms of this license: - Java Native Access (from https://github.com/java-native-access/jna) - Java Native Access Platform (from https://github.com/java-native-access/jna) - Javassist (from http://www.javassist.org/) -- Logback Classic Module (from ) -- Logback Core Module (from ) - Microsoft Application Insights Java SDK Core (from https://github.com/Microsoft/ApplicationInsights-Java) - Microsoft Application Insights Java SDK Spring Boot starter (from https://github.com/Microsoft/ApplicationInsights-Java) - Microsoft Application Insights Java SDK Web Module (from https://github.com/Microsoft/ApplicationInsights-Java) -- GitLab From 4fdbc6a4971d1802b6ceeb213f87b262d1136aa2 Mon Sep 17 00:00:00 2001 From: Harshit Aggarwal Date: Thu, 6 Aug 2020 14:27:09 +0530 Subject: [PATCH 12/12] Minor fix --- .../azure/multitenancy/TenantFactoryImpl.java | 6 ++++-- .../osdu/azure/multitenancy/TenantInfoDoc.java | 8 ++++++-- .../multitenancy/TenantFactoryImplTest.java | 17 ++++++++++++----- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java index 34e04d9d..9d47e4d9 100644 --- a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java +++ b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImpl.java @@ -105,11 +105,13 @@ public class TenantFactoryImpl implements ITenantFactory { this.tenants = new HashMap<>(); // TODO partition id should not be required because tenant details will be kept in a known partition - cosmosStore.findAllItems(DpsHeaders.DATA_PARTITION_ID, cosmosDBConfiguration.getCosmosDBName(), cosmosDBConfiguration.getTenantInfoContainer(), TenantInfoDoc.class).forEach( - tenantInfoDoc -> { + cosmosStore.findAllItems(DpsHeaders.DATA_PARTITION_ID, cosmosDBConfiguration.getCosmosDBName(), cosmosDBConfiguration.getTenantInfoContainer(), TenantInfoDoc.class). + forEach(tenantInfoDoc -> { TenantInfo ti = new TenantInfo(); String tenantName = tenantInfoDoc.getId(); ti.setName(tenantName); + ti.setComplianceRuleSet(tenantInfoDoc.getComplianceRuleSet()); + ti.setDataPartitionId(tenantName); this.tenants.put(tenantName, ti); } ); diff --git a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java index 7c2f72d5..dbdfc307 100644 --- a/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java +++ b/src/main/java/org/opengroup/osdu/azure/multitenancy/TenantInfoDoc.java @@ -14,16 +14,20 @@ package org.opengroup.osdu.azure.multitenancy; +import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Data; -import lombok.Getter; +import lombok.NoArgsConstructor; /** * TenantInfoDoc class. */ @Data @AllArgsConstructor -@Getter +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class TenantInfoDoc { private String id; + private String serviceprincipalAppId; + private String complianceRuleSet; + private String[] groups; } diff --git a/src/test/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImplTest.java b/src/test/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImplTest.java index 345ec8e5..63714e97 100644 --- a/src/test/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImplTest.java +++ b/src/test/java/org/opengroup/osdu/azure/multitenancy/TenantFactoryImplTest.java @@ -31,6 +31,9 @@ public class TenantFactoryImplTest { private static final String cosmosDatabase = "cosmos-database"; private static final String cosmosContainer = "tenant-info"; private static final String notFound = "not-found"; + private static final String[] groups = {"first"}; + private static final String serviceprincipalAppId = "sp-id"; + private static final String complianceRuleSet = "compliance-rule-set"; @InjectMocks private TenantFactoryImpl tenantFactory; @@ -49,7 +52,7 @@ public class TenantFactoryImplTest { @Test public void returnsTrueWhenTenantNameFound() { - TenantInfoDoc doc = new TenantInfoDoc(tenantName); + TenantInfoDoc doc = new TenantInfoDoc(tenantName, serviceprincipalAppId, complianceRuleSet, groups); doReturn(Collections.singletonList(doc)).when(cosmosStore).findAllItems(eq(DpsHeaders.DATA_PARTITION_ID), eq(cosmosDatabase), eq(cosmosContainer), any()); boolean result = tenantFactory.exists(tenantName); @@ -59,7 +62,7 @@ public class TenantFactoryImplTest { @Test public void returnsFalseWhenTenantNameNotFound() { - TenantInfoDoc doc = new TenantInfoDoc(tenantName + notFound); + TenantInfoDoc doc = new TenantInfoDoc(tenantName + notFound, serviceprincipalAppId, complianceRuleSet, groups); doReturn(Collections.singletonList(doc)).when(cosmosStore).findAllItems(eq(DpsHeaders.DATA_PARTITION_ID), eq(cosmosDatabase), eq(cosmosContainer), any()); boolean result = tenantFactory.exists(tenantName); @@ -69,20 +72,22 @@ public class TenantFactoryImplTest { @Test public void returnsTenantInfoObjectWhenTenantNameFound() { - TenantInfoDoc doc = new TenantInfoDoc(tenantName); + TenantInfoDoc doc = new TenantInfoDoc(tenantName, serviceprincipalAppId, complianceRuleSet, groups); doReturn(Collections.singletonList(doc)).when(cosmosStore).findAllItems(eq(DpsHeaders.DATA_PARTITION_ID), eq(cosmosDatabase), eq(cosmosContainer), any()); TenantInfo result = tenantFactory.getTenantInfo(tenantName); TenantInfo expected = new TenantInfo(); expected.setName(tenantName); + expected.setDataPartitionId(tenantName); + expected.setComplianceRuleSet(complianceRuleSet); assertEquals(expected, result); } @Test public void returnsNullWhenTenantNameNotFound() { - TenantInfoDoc doc = new TenantInfoDoc(tenantName + notFound); + TenantInfoDoc doc = new TenantInfoDoc(tenantName + notFound, serviceprincipalAppId, complianceRuleSet, groups); doReturn(Collections.singletonList(doc)).when(cosmosStore).findAllItems(eq(DpsHeaders.DATA_PARTITION_ID), eq(cosmosDatabase), eq(cosmosContainer), any()); TenantInfo result = tenantFactory.getTenantInfo(tenantName); @@ -92,13 +97,15 @@ public class TenantFactoryImplTest { @Test public void returnsListOfAllTenants() { - TenantInfoDoc doc = new TenantInfoDoc(tenantName); + TenantInfoDoc doc = new TenantInfoDoc(tenantName, serviceprincipalAppId, complianceRuleSet, groups); doReturn(Collections.singletonList(doc)).when(cosmosStore).findAllItems(eq(DpsHeaders.DATA_PARTITION_ID), eq(cosmosDatabase), eq(cosmosContainer), any()); List result = new ArrayList<>(tenantFactory.listTenantInfo()); TenantInfo tenantInfo = new TenantInfo(); tenantInfo.setName(tenantName); + tenantInfo.setDataPartitionId(tenantName); + tenantInfo.setComplianceRuleSet(complianceRuleSet); List expected = Collections.singletonList(tenantInfo); -- GitLab