diff --git a/NOTICE b/NOTICE index 09e1d8aed7adc700949b23bc3134de395abfc102..ff4edac97b6dbc36e00c88221218a72e62fce53e 100644 --- a/NOTICE +++ b/NOTICE @@ -24,7 +24,7 @@ The following software have components provided under the terms of this license: - Apache Log4j API (from ) - Apache Log4j Core (from ) - Apache Log4j JUL Adapter (from ) -- Apache Log4j to SLF4J Adapter (from ) +- Apache Log4j SLF4J Binding (from ) - AssertJ fluent assertions (from ) - Asynchronous Http Client (from ) - Asynchronous Http Client Netty Utils (from ) @@ -129,7 +129,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 Security Starter (from http://projects.spring.io/spring-boot/) - Spring Boot Starter (from http://projects.spring.io/spring-boot/) - Spring Boot Test (from http://projects.spring.io/spring-boot/) @@ -268,8 +267,6 @@ EPL-1.0 The following software have components provided under the terms of this license: - JUnit (from http://junit.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) @@ -320,8 +317,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) diff --git a/src/main/java/org/opengroup/osdu/azure/entitlements/di/CosmosContainerConfig.java b/src/main/java/org/opengroup/osdu/azure/entitlements/di/CosmosContainerConfig.java index 7819a74d710d4b3e269388c69583627db55176b3..10a43f281d6de12c82d573717aee450510e86c79 100644 --- a/src/main/java/org/opengroup/osdu/azure/entitlements/di/CosmosContainerConfig.java +++ b/src/main/java/org/opengroup/osdu/azure/entitlements/di/CosmosContainerConfig.java @@ -1,44 +1,24 @@ package org.opengroup.osdu.azure.entitlements.di; -import com.azure.cosmos.CosmosClient; -import com.azure.cosmos.CosmosContainer; -import org.opengroup.osdu.common.Validators; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; -import javax.inject.Named; - public class CosmosContainerConfig { - @Autowired - private CosmosClient cosmosClient; - - @Autowired - private String cosmosDBName; - @Value("${userinfo.container.name}") private String userInfoContainerName; @Value("${tenantinfo.container.name}") private String tenantInfoContainerName; - @Bean - @Named("userInfoContainer") - public CosmosContainer UserInfoContainer() { - Validators.checkNotNull(cosmosClient, "Cosmos client cannot be null"); - Validators.checkNotNullAndNotEmpty(cosmosDBName, "Cosmos DB Name"); - Validators.checkNotNullAndNotEmpty(userInfoContainerName, "Cosmos container name"); - return cosmosClient.getDatabase(cosmosDBName).getContainer(userInfoContainerName); + public String userInfoContainer(){ + return userInfoContainerName; } @Bean - @Named("tenantInfoContainer") - public CosmosContainer TenantInfoContainer() { - Validators.checkNotNull(cosmosClient, "Cosmos client cannot be null"); - Validators.checkNotNullAndNotEmpty(cosmosDBName, "Cosmos DB Name"); - Validators.checkNotNullAndNotEmpty(tenantInfoContainerName, "Cosmos container name"); - return cosmosClient.getDatabase(cosmosDBName).getContainer(tenantInfoContainerName); + public String tenantInfoContainer(){ + return tenantInfoContainerName; } + } \ No newline at end of file diff --git a/src/main/java/org/opengroup/osdu/azure/entitlements/repository/GroupInfoRepository.java b/src/main/java/org/opengroup/osdu/azure/entitlements/repository/GroupInfoRepository.java index 46ede777743e6ee08175b5450669f61a167d4c77..9ba93141cc509d5d51c3e96aab1dd2c9919d14c6 100644 --- a/src/main/java/org/opengroup/osdu/azure/entitlements/repository/GroupInfoRepository.java +++ b/src/main/java/org/opengroup/osdu/azure/entitlements/repository/GroupInfoRepository.java @@ -14,16 +14,15 @@ package org.opengroup.osdu.azure.entitlements.repository; -import com.azure.cosmos.CosmosContainer; import org.apache.http.HttpStatus; -import org.opengroup.osdu.azure.CosmosFacade; +import org.opengroup.osdu.azure.CosmosStore; import org.opengroup.osdu.azure.entitlements.model.GroupInfoDoc; import org.opengroup.osdu.azure.entitlements.model.TenantInfoDoc; import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; -import javax.inject.Named; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -33,8 +32,16 @@ import java.util.Optional; public class GroupInfoRepository { @Autowired - @Named("tenantInfoContainer") - private CosmosContainer tenantInfoContainer; + private CosmosStore cosmosStore; + + @Autowired + private String tenantInfoContainer; + + @Autowired + private String cosmosDBName; + + @Autowired + private DpsHeaders headers; /** * Method to update the group in Azure Cosmos DB. @@ -56,7 +63,7 @@ public class GroupInfoRepository { groupNameList.add(groupName); tenantInfoDoc.setGroups(groupNameList.toArray(new String[0])); - CosmosFacade.upsertItem(tenantInfoContainer, tenantInfoDoc); + cosmosStore.upsertItem(headers.getPartitionId(), cosmosDBName, tenantInfoContainer, tenantInfoDoc); } /** @@ -65,6 +72,6 @@ public class GroupInfoRepository { * @return The tenant info. */ private Optional findTenantInfo(String tenantId) { - return CosmosFacade.findItem(tenantInfoContainer, tenantId, tenantId, TenantInfoDoc.class); + return cosmosStore.findItem(headers.getPartitionId(), cosmosDBName, tenantInfoContainer, tenantId, tenantId, TenantInfoDoc.class); } } \ No newline at end of file diff --git a/src/main/java/org/opengroup/osdu/azure/entitlements/repository/UserInfoRepository.java b/src/main/java/org/opengroup/osdu/azure/entitlements/repository/UserInfoRepository.java index 2aa3942ca3ccf9c2d99b8321c169e01f1854c165..c661270ad0a6e288263a09b8f0d85f14014e0e56 100644 --- a/src/main/java/org/opengroup/osdu/azure/entitlements/repository/UserInfoRepository.java +++ b/src/main/java/org/opengroup/osdu/azure/entitlements/repository/UserInfoRepository.java @@ -14,16 +14,18 @@ package org.opengroup.osdu.azure.entitlements.repository; - -import com.azure.cosmos.*; -import org.opengroup.osdu.azure.CosmosFacade; +import com.azure.cosmos.FeedOptions; +import com.azure.cosmos.SqlParameter; +import com.azure.cosmos.SqlParameterList; +import com.azure.cosmos.SqlQuerySpec; +import org.opengroup.osdu.azure.CosmosStore; import org.opengroup.osdu.azure.entitlements.model.UserInfoDoc; import org.opengroup.osdu.azure.entitlements.model.UserTenantItem; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Repository; -import javax.inject.Named; import java.util.Arrays; import java.util.Optional; import java.util.logging.Logger; @@ -31,12 +33,19 @@ import java.util.logging.Logger; @Repository public class UserInfoRepository { - private static Logger logger = Logger.getLogger(UserInfoRepository.class.getName()); @Autowired - @Named("userInfoContainer") - private CosmosContainer userInfoContainer; + private CosmosStore cosmosStore; + + @Autowired + private String userInfoContainer; + + @Autowired + private String cosmosDBName; + + @Autowired + private DpsHeaders headers; /** * Accessor for getting the tenant groips from Azure Cosmos DB. @@ -69,7 +78,7 @@ public class UserInfoRepository UserTenantItem existingTenant = getTenant(userInfoDoc, tenantName); existingTenant.setGroups(tenantGroups); - CosmosFacade.upsertItem(userInfoContainer, userInfoDoc); + cosmosStore.upsertItem(headers.getPartitionId(), cosmosDBName, userInfoContainer, userInfoDoc); } /** @@ -99,7 +108,7 @@ public class UserInfoRepository FeedOptions options = new FeedOptions(); options.setEnableCrossPartitionQuery(true); - String[] members = CosmosFacade.queryItems(userInfoContainer, query, options, UserInfoDoc.class).stream().map(doc -> doc.getId()).toArray(String[]::new); + String[] members = cosmosStore.queryItems(headers.getPartitionId(), cosmosDBName, userInfoContainer, query, options, UserInfoDoc.class).stream().map(doc -> doc.getId()).toArray(String[]::new); return members; } @@ -117,7 +126,7 @@ public class UserInfoRepository FeedOptions options = new FeedOptions(); options.setEnableCrossPartitionQuery(true); - String[] members = CosmosFacade.queryItems(userInfoContainer, query, options, UserInfoDoc.class).stream().map(doc -> doc.getUid()).toArray(String[]::new); + String[] members = cosmosStore.queryItems(headers.getPartitionId(), cosmosDBName, userInfoContainer, query, options, UserInfoDoc.class).stream().map(doc -> doc.getUid()).toArray(String[]::new); return members; } @@ -127,7 +136,7 @@ public class UserInfoRepository * @param upn The UPN of the user. This is also the ID and partition key of the Cosmos document */ public Optional findUserInfo(String upn) { - return CosmosFacade.findItem(userInfoContainer, upn, upn, UserInfoDoc.class); + return cosmosStore.findItem(headers.getPartitionId(), cosmosDBName, userInfoContainer, upn, upn, UserInfoDoc.class); } /** @@ -136,7 +145,7 @@ public class UserInfoRepository * @return */ public boolean exists(String id) { - return CosmosFacade.findItem(userInfoContainer, id, id, UserInfoDoc.class).isPresent(); + return cosmosStore.findItem(headers.getPartitionId(),cosmosDBName, userInfoContainer, id, id, UserInfoDoc.class).isPresent(); } /** @@ -144,7 +153,7 @@ public class UserInfoRepository * @param entity */ public void create(UserInfoDoc entity) { - CosmosFacade.upsertItem(userInfoContainer, entity); + cosmosStore.upsertItem(headers.getPartitionId(),cosmosDBName, userInfoContainer, entity); } /** @@ -152,13 +161,13 @@ public class UserInfoRepository * @param entity */ public void update(UserInfoDoc entity) { - CosmosFacade.upsertItem(userInfoContainer, entity); + cosmosStore.upsertItem(headers.getPartitionId(),cosmosDBName, userInfoContainer, entity); } /** * Method to delete a user profile in Azure Cosmos DB. * @param id */ - public void delete(String id) { CosmosFacade.deleteItem(userInfoContainer, id, id); } + public void delete(String id) { cosmosStore.deleteItem(headers.getPartitionId(),cosmosDBName, userInfoContainer, id, id); } } diff --git a/src/test/java/org/opengroup/osdu/azure/entitlements/repository/GroupInfoRepositoryTest.java b/src/test/java/org/opengroup/osdu/azure/entitlements/repository/GroupInfoRepositoryTest.java index 67d619febc00fd927a84522792460c4889b9e073..f09b2e2772522db94aa0087a123b7c960a614cfb 100644 --- a/src/test/java/org/opengroup/osdu/azure/entitlements/repository/GroupInfoRepositoryTest.java +++ b/src/test/java/org/opengroup/osdu/azure/entitlements/repository/GroupInfoRepositoryTest.java @@ -1,6 +1,6 @@ package org.opengroup.osdu.azure.entitlements.repository; -import com.azure.cosmos.*; +import com.azure.cosmos.CosmosClientException; import org.apache.http.HttpStatus; import org.junit.Before; import org.junit.Test; @@ -8,44 +8,41 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import org.opengroup.osdu.azure.CosmosFacade; +import org.opengroup.osdu.azure.CosmosStore; import org.opengroup.osdu.azure.entitlements.model.GroupInfoDoc; import org.opengroup.osdu.azure.entitlements.model.TenantInfoDoc; import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; -import javax.inject.Named; import java.io.IOException; +import java.util.Optional; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.lenient; @RunWith(MockitoJUnitRunner.class) public class GroupInfoRepositoryTest { - @Mock - @Named("tenantInfoContainer") - private CosmosContainer cosmosContainer; - @Mock - private CosmosItem cosmosItem; + private static final String dataPartitionId = "data-partition-id"; @Mock - private CosmosItemResponse cosmosResponse; + private CosmosStore cosmosStore; @Mock - private CosmosItemProperties cosmosItemProperties; + private DpsHeaders headers; @InjectMocks private GroupInfoRepository repo; @Before - public void init() throws CosmosClientException { - // mock the common cosmos request/response pattern that most tests need - doReturn(cosmosItem).when(cosmosContainer).getItem(any(), any()); - doReturn(cosmosResponse).when(cosmosItem).read(any()); - doReturn(cosmosItemProperties).when(cosmosResponse).getProperties(); + public void init() { + lenient().doReturn(dataPartitionId).when(headers).getPartitionId(); } @Test(expected = AppException.class) @@ -53,9 +50,10 @@ public class GroupInfoRepositoryTest { GroupInfoDoc groupInfoDoc = new GroupInfoDoc(); groupInfoDoc.setId("opendes"); - doThrow(CosmosClientException.class) - .when(cosmosItem) - .read(any()); + doThrow(AppException.class) + .when(cosmosStore) + .findItem(anyString(), any(), any(), any(), any(), any()); + repo.updateGroup(groupInfoDoc); } @@ -68,7 +66,9 @@ public class GroupInfoRepositoryTest { TenantInfoDoc tenantInfoDoc = new TenantInfoDoc(); tenantInfoDoc.setId("opendes"); tenantInfoDoc.setGroups(new String[] {"users.test.editors", "users.test.viewers"}); - when(CosmosFacade.findItem(cosmosContainer, anyString(),anyString(), TenantInfoDoc.class)).thenReturn(null); + + doReturn(Optional.empty()).when(cosmosStore).findItem(anyString(), any(), any(), anyString(), anyString(), any()); + try { repo.updateGroup(groupInfoDoc); } catch (AppException apx) { @@ -88,7 +88,7 @@ public class GroupInfoRepositoryTest { tenantInfoDoc.setId("opendes"); tenantInfoDoc.setGroups(new String[] {"users.test.editors", "users.test.viewers"}); - doReturn(tenantInfoDoc).when(cosmosItemProperties).getObject(any()); + doReturn(Optional.of(tenantInfoDoc)).when(cosmosStore).findItem(anyString(), any(), any(), anyString(), anyString(), any()); try { repo.updateGroup(groupInfoDoc); @@ -109,7 +109,8 @@ public class GroupInfoRepositoryTest { tenantInfoDoc.setId("opendes"); tenantInfoDoc.setGroups(new String[] {"users.test.viewers"}); - doReturn(tenantInfoDoc).when(cosmosItemProperties).getObject(any()); + doReturn(Optional.of(tenantInfoDoc)).when(cosmosStore).findItem(anyString(), any(), any(), anyString(), anyString(), any()); + doNothing().when(cosmosStore).upsertItem(any(), any(), any(), any()); try { repo.updateGroup(groupInfoDoc); } catch (Exception ex) { diff --git a/src/test/java/org/opengroup/osdu/azure/entitlements/repository/UserInfoRepositoryTest.java b/src/test/java/org/opengroup/osdu/azure/entitlements/repository/UserInfoRepositoryTest.java index 676920098e3575df9c7530b967c391d63c3c58c0..535f21873fb729f89b17e6b33ecc30f6543f313f 100644 --- a/src/test/java/org/opengroup/osdu/azure/entitlements/repository/UserInfoRepositoryTest.java +++ b/src/test/java/org/opengroup/osdu/azure/entitlements/repository/UserInfoRepositoryTest.java @@ -14,8 +14,7 @@ package org.opengroup.osdu.azure.entitlements.repository; - -import com.azure.cosmos.*; +import com.azure.cosmos.CosmosClientException; import org.hamcrest.CoreMatchers; import org.junit.Before; import org.junit.Test; @@ -23,95 +22,69 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.opengroup.osdu.azure.CosmosStore; import org.opengroup.osdu.azure.entitlements.model.UserInfoDoc; import org.opengroup.osdu.azure.entitlements.model.UserTenantItem; import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; import org.springframework.security.access.AccessDeniedException; import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.Optional; import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.lenient; @RunWith(MockitoJUnitRunner.class) public class UserInfoRepositoryTest { - @Mock - private CosmosContainer cosmosContainer; - @Mock - private CosmosItem cosmosItem; + private static final String dataPartitionId = "data-partition-id"; @Mock - private CosmosItemResponse cosmosResponse; + private CosmosStore cosmosStore; @Mock - private CosmosItemProperties cosmosItemProperties; + private DpsHeaders headers; @InjectMocks private UserInfoRepository repo; @Before - public void init() throws CosmosClientException { - // mock the common cosmos request/response pattern that most tests need - doReturn(cosmosItem).when(cosmosContainer).getItem(any(), any()); - doReturn(cosmosResponse).when(cosmosItem).read(any()); - doReturn(cosmosItemProperties).when(cosmosResponse).getProperties(); + public void init() { + lenient().doReturn(dataPartitionId).when(headers).getPartitionId(); } @Test(expected = AppException.class) public void errorNotSwallowed_whenUnexpectedExceptionThrown() throws CosmosClientException { - doThrow(CosmosClientException.class) - .when(cosmosItem) - .read(any()); - repo.getTenantGroups("dummy-upn", "dummy-tenant"); - } - - @Test(expected = AccessDeniedException.class) - public void accessDeniedThrown_noUser_dueToNotFoundException() throws CosmosClientException { - doThrow(NotFoundException.class) - .when(cosmosItem) - .read(any()); - repo.getTenantGroups("dummy-upn", "dummy-tenant"); - } - - @Test(expected = AccessDeniedException.class) - public void accessDeniedThrown_noUser_dueToIOException() throws IOException { - doThrow(IOException.class) - .when(cosmosItemProperties) - .getObject(any()); + doThrow(AppException.class).when(cosmosStore).findItem(anyString(), any(), any(), any(), any(), any()); repo.getTenantGroups("dummy-upn", "dummy-tenant"); } @Test(expected = AccessDeniedException.class) - public void accessDeniedThrown_noUser_dueToNullResponse() throws IOException { - doReturn(null) - .when(cosmosItemProperties) - .getObject(any()); + public void accessDeniedThrown_noUser_dueToEmptyResponse() throws IOException { + doReturn(Optional.empty()).when(cosmosStore).findItem(anyString(), any(), any(), any(), any(), any()); repo.getTenantGroups("dummy-upn", "dummy-tenant"); } @Test(expected = AccessDeniedException.class) public void accessDeniedThrown_userHasNoTenantAccess() throws IOException { - UserInfoDoc userInfo = getUserInfoWithTenantGroups("dummy-upn", "t1", "t2"); - doReturn(userInfo) - .when(cosmosItemProperties) - .getObject(any()); - + Optional userInfo = Optional.of(getUserInfoWithTenantGroups("dummy-upn", "t1", "t2")); + doReturn(userInfo).when(cosmosStore).findItem(anyString(), any(), any(), anyString(), anyString(), any()); repo.getTenantGroups("dummy-upn", "t3"); } @Test public void correctTenantGroupsReturned_userHasTenantAccess() throws IOException { - UserInfoDoc userInfo = getUserInfoWithTenantGroups("dummy-upn", "t1"); - doReturn(userInfo) - .when(cosmosItemProperties) - .getObject(any()); + Optional userInfo = Optional.of(getUserInfoWithTenantGroups("dummy-upn", "t1")); + doReturn(userInfo).when(cosmosStore).findItem(anyString(), any(), any(), anyString(), anyString(), any()); - String[] expectedGroups = userInfo.getTenants()[0].getGroups(); + String[] expectedGroups = userInfo.get().getTenants()[0].getGroups(); List actualGroups = Arrays.asList(repo.getTenantGroups("dummy-upn", "t1")); assertThat("TenantGroups did return expected groups", actualGroups, CoreMatchers.hasItems(expectedGroups[0],expectedGroups[1])); @@ -119,12 +92,10 @@ public class UserInfoRepositoryTest { @Test public void correctTenantGroupsReturned_userHasTenantAccess_ignoreTenantCasing() throws IOException { - UserInfoDoc userInfo = getUserInfoWithTenantGroups("dummy-upn", "t1"); - doReturn(userInfo) - .when(cosmosItemProperties) - .getObject(any()); + Optional userInfo = Optional.of(getUserInfoWithTenantGroups("dummy-upn", "t1")); + doReturn(userInfo).when(cosmosStore).findItem(anyString(), any(), any(), anyString(), anyString(), any()); - String[] expectedGroups = userInfo.getTenants()[0].getGroups(); + String[] expectedGroups = userInfo.get().getTenants()[0].getGroups(); List actualGroups = Arrays.asList(repo.getTenantGroups("dummy-upn", "T1")); assertThat("TenantGroups did return expected groups", actualGroups, CoreMatchers.hasItems(expectedGroups[0],expectedGroups[1]));