diff --git a/indexer-service-gcp/src/main/java/org/opendes/indexer/IndexerGcpApplication.java b/indexer-service-gcp/src/main/java/org/opendes/indexer/IndexerGcpApplication.java index d12ce6f2941f23111dccaf04a2f4cbacf225ba8d..f066dd1436dbe75d6db388350df458786df12a0f 100644 --- a/indexer-service-gcp/src/main/java/org/opendes/indexer/IndexerGcpApplication.java +++ b/indexer-service-gcp/src/main/java/org/opendes/indexer/IndexerGcpApplication.java @@ -4,8 +4,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; @SpringBootApplication(exclude = { SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class }) +@Configuration +@ComponentScan("org.opendes.core") public class IndexerGcpApplication { public static void main(String[] args) { diff --git a/indexer-service-gcp/src/main/java/org/opendes/indexer/di/DpsHeaderFactory.java b/indexer-service-gcp/src/main/java/org/opendes/indexer/di/DpsHeaderFactory.java index e9f400994aedaa59ca606996097ca8d45087d142..cd0b66653ab0d5f852c5777fac1be2d220a044fa 100644 --- a/indexer-service-gcp/src/main/java/org/opendes/indexer/di/DpsHeaderFactory.java +++ b/indexer-service-gcp/src/main/java/org/opendes/indexer/di/DpsHeaderFactory.java @@ -21,7 +21,7 @@ public class DpsHeaderFactory extends DpsHeaders { .collect(Collectors.toMap(h -> h, request::getHeader)); DpsHeaders dps = DpsHeaders.createFromMap(headers); dps.getHeaders().forEach( (k, v) -> this.put(k,v)); - //Added for Indexer Queue + //Added for Indexer headers.forEach((k, v) -> this.put(k,v)); } } \ No newline at end of file diff --git a/indexer-service-gcp/src/main/java/org/opendes/indexer/di/TenantInfoFactory.java b/indexer-service-gcp/src/main/java/org/opendes/indexer/di/TenantInfoFactory.java index e7bcd5df8fb56faa26b09215be8069c84d0af143..249d49334751523260e1552db6c9b9a6c53fb071 100644 --- a/indexer-service-gcp/src/main/java/org/opendes/indexer/di/TenantInfoFactory.java +++ b/indexer-service-gcp/src/main/java/org/opendes/indexer/di/TenantInfoFactory.java @@ -11,7 +11,7 @@ import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; @Log -@Component +@Component("TenantInfoFactoryGcp") @RequestScope public class TenantInfoFactory extends AbstractFactoryBean<TenantInfo> { @Autowired @@ -21,9 +21,7 @@ public class TenantInfoFactory extends AbstractFactoryBean<TenantInfo> { private DpsHeaders headers; @Override protected TenantInfo createInstance() throws Exception { - log.info("TENANTINFOFACTORY HEADERS: " + headers.toString()); String id = this.headers.getPartitionIdWithFallbackToAccountId(); - log.info("TENANTINFOFACTORY ID: " + id); return this.tenantFactory.getTenantInfo(id); } @Override diff --git a/indexer-service-gcp/src/main/java/org/opendes/indexer/persistence/ElasticRepositoryDatastore.java b/indexer-service-gcp/src/main/java/org/opendes/indexer/persistence/ElasticRepositoryDatastore.java index e6f1248a5646d1ed1586214d898652865a1b5591..6731588b01719990f434eb9c68da2f866f72d4bd 100644 --- a/indexer-service-gcp/src/main/java/org/opendes/indexer/persistence/ElasticRepositoryDatastore.java +++ b/indexer-service-gcp/src/main/java/org/opendes/indexer/persistence/ElasticRepositoryDatastore.java @@ -27,8 +27,9 @@ import org.opendes.core.util.Config; import org.opendes.core.util.Preconditions; import org.opendes.indexer.kms.KmsClient; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; - +@Component public class ElasticRepositoryDatastore implements ElasticRepository { static final String HOST = "host"; diff --git a/indexer-service-gcp/src/main/java/org/opendes/indexer/service/ElasticSettingServiceImpl.java b/indexer-service-gcp/src/main/java/org/opendes/indexer/service/ElasticSettingServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..649b65037746cba193c29acd8710e4822d7aba8d --- /dev/null +++ b/indexer-service-gcp/src/main/java/org/opendes/indexer/service/ElasticSettingServiceImpl.java @@ -0,0 +1,65 @@ +// Copyright 2017-2019, Schlumberger +// +// 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.opendes.indexer.service; + +import org.apache.http.HttpStatus; +import org.opendes.client.multitenancy.TenantInfo; +import org.opendes.core.cache.ElasticCredentialsCache; +import org.opendes.core.logging.JaxRsDpsLog; +import org.opendes.core.model.ClusterSettings; +import org.opendes.core.persistence.ElasticRepository; +import org.opendes.core.service.ElasticSettingService; +import org.opendes.core.service.TenantInfoService; +import org.opendes.core.util.AppException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Service +public class ElasticSettingServiceImpl implements ElasticSettingService { + + @Autowired + private TenantInfoService tenantInfoServiceProvider; + @Autowired + private ElasticRepository elasticRepository; + @Autowired + private ElasticCredentialsCache elasticCredentialCache; + @Autowired + private JaxRsDpsLog log; + + @Value("${GAE_SERVICE}") + public String GAE_SERVICE; + + @Override + public ClusterSettings getElasticClusterInformation() { + + TenantInfo tenantInfo = this.tenantInfoServiceProvider.getTenantInfo(); + + String cacheKey = String.format("%s-%s", GAE_SERVICE, tenantInfo.getName()); + ClusterSettings clusterInfo = this.elasticCredentialCache.get(cacheKey); + if (clusterInfo != null) { + return clusterInfo; + } + log.warning(String.format("elastic-credential cache missed for tenant: %s", tenantInfo.getName())); + + clusterInfo = this.elasticRepository.getElasticClusterSettings(tenantInfo); + if (clusterInfo == null) { + throw new AppException(HttpStatus.SC_NOT_FOUND, "Tenant not found", "No information about the given tenant was found"); + } + + this.elasticCredentialCache.put(cacheKey, clusterInfo); + return clusterInfo; + } +} diff --git a/indexer-service-gcp/src/main/java/org/opendes/indexer/service/TenantInfoServiceImpl.java b/indexer-service-gcp/src/main/java/org/opendes/indexer/service/TenantInfoServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..51d1217416dbb48809ca5fb9f93fdc3cdbdce4e5 --- /dev/null +++ b/indexer-service-gcp/src/main/java/org/opendes/indexer/service/TenantInfoServiceImpl.java @@ -0,0 +1,47 @@ +// Copyright 2017-2019, Schlumberger +// +// 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.opendes.indexer.service; + +import org.opendes.client.api.DpsHeaders; +import org.opendes.client.multitenancy.ITenantFactory; +import org.opendes.client.multitenancy.TenantInfo; +import org.opendes.core.service.TenantInfoService; +import org.opendes.core.util.AppException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class TenantInfoServiceImpl implements TenantInfoService { + + @Autowired + private ITenantFactory tenantFactory; + @Autowired + private DpsHeaders headersInfo; + + @Autowired + private TenantInfo tenantInfo; + + public TenantInfo getTenantInfo() { + + if(this.headersInfo == null) + throw AppException.createUnauthorized(String.format("could not retrieve headers info ")); + + TenantInfo tenantInfo = this.tenantFactory.getTenantInfo(this.headersInfo.getPartitionId()); + if (tenantInfo == null) + throw AppException.createUnauthorized(String.format("could not retrieve tenant info for account id: %s", headersInfo.getPartitionId())); + + return tenantInfo; + } +} \ No newline at end of file diff --git a/indexer-service-gcp/src/test/java/org/opendes/indexer/service/ElasticSettingServiceTest.java b/indexer-service-gcp/src/test/java/org/opendes/indexer/service/ElasticSettingServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..51b2438fb166f3306ceaa68e98c592a69c2c597a --- /dev/null +++ b/indexer-service-gcp/src/test/java/org/opendes/indexer/service/ElasticSettingServiceTest.java @@ -0,0 +1,103 @@ +// Copyright 2017-2019, Schlumberger +// +// 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.opendes.indexer.service; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; +import org.opendes.client.multitenancy.TenantInfo; +import org.opendes.core.cache.ElasticCredentialsCache; +import org.opendes.core.logging.JaxRsDpsLog; +import org.opendes.core.model.ClusterSettings; +import org.opendes.core.persistence.ElasticRepository; +import org.opendes.core.service.TenantInfoService; +import org.opendes.core.util.AppException; +import org.opendes.core.util.Config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; + +@Ignore +@RunWith(MockitoJUnitRunner.class) +public class ElasticSettingServiceTest { + + @Mock + private TenantInfoService tenantInfoService; + @Mock + private ElasticRepository elasticRepository; + @Mock + private ElasticCredentialsCache elasticCredentialCache; + @Mock + private JaxRsDpsLog log; + + @Mock + private Config config; + + @InjectMocks + private ElasticSettingServiceImpl sut; + + private TenantInfo tenantInfo; + private ClusterSettings clusterSettings; + private final String host = "db5c51c1.us-central1.gcp.cloud.es.io"; + private final int port = 9243; + private final String credentials = "name:password"; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + when(Config.getDeployedServiceId()).thenReturn("search"); + + tenantInfo = new TenantInfo(); + tenantInfo.setName("tenant1"); + when(this.tenantInfoService.getTenantInfo()).thenReturn(tenantInfo); + + clusterSettings = ClusterSettings.builder().host(host).port(port).userNameAndPassword(credentials).build(); + } + + @Test + public void should_getValid_clusterSettings_fromCache() { + when(this.elasticCredentialCache.get("search-tenant1")).thenReturn(clusterSettings); + + ClusterSettings response = this.sut.getElasticClusterInformation(); + assertNotNull(response); + assertEquals(response.getHost(), host); + assertEquals(response.getPort(), port); + assertEquals(response.getUserNameAndPassword(), credentials); + } + + @Test + public void should_getValid_clusterSettings_fromDatastore() { + when(this.elasticRepository.getElasticClusterSettings(tenantInfo)).thenReturn(clusterSettings); + + ClusterSettings response = this.sut.getElasticClusterInformation(); + assertNotNull(response); + assertEquals(response.getHost(), host); + assertEquals(response.getPort(), port); + assertEquals(response.getUserNameAndPassword(), credentials); + } + + @Test(expected = AppException.class) + public void should_throwAppException_when_tenantClusterInfo_not_found() throws AppException { + when(this.elasticRepository.getElasticClusterSettings(tenantInfo)).thenReturn(null); + + this.sut.getElasticClusterInformation(); + } +} diff --git a/indexer-service-gcp/src/test/java/org/opendes/indexer/service/TenantInfoServiceTest.java b/indexer-service-gcp/src/test/java/org/opendes/indexer/service/TenantInfoServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e632477fc29a1abb4064ac105daf871785ac74e0 --- /dev/null +++ b/indexer-service-gcp/src/test/java/org/opendes/indexer/service/TenantInfoServiceTest.java @@ -0,0 +1,89 @@ +// Copyright 2017-2019, Schlumberger +// +// 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.opendes.indexer.service; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.opendes.client.api.DpsHeaders; +import org.opendes.client.multitenancy.ITenantFactory; +import org.opendes.client.multitenancy.TenantInfo; +import org.opendes.core.util.AppException; +import org.opendes.core.util.HeadersInfo; +import org.springframework.http.HttpHeaders; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; + +@RunWith(SpringRunner.class) +public class TenantInfoServiceTest { + + private static final String HEADER_NAME = "ANY_HEADER"; + private static final String HEADER_VALUE = "ANY_VALUE"; + + @Mock + private ITenantFactory tenantFactory; + @InjectMocks + private HeadersInfo headersInfo; + @InjectMocks + private TenantInfoServiceImpl sut; + + @Mock + private TenantInfo info; + + @Mock + private HttpHeaders httpHeaders; + + @InjectMocks + private DpsHeaders HEADERS; + + @Before + public void setup() { + HEADERS.put(HEADER_NAME, HEADER_VALUE); + } + + @Ignore + @Test + public void should_return_validTenant_given_validAccountId() { + + when(this.info.getName()).thenReturn("tenant1"); + when(tenantFactory.getTenantInfo("tenant1")).thenReturn(info); + + when(this.headersInfo.getHeaders()).thenReturn(HEADERS); + + when(this.headersInfo.getPartitionId()).thenReturn("tenant1"); + + when(this.sut.getTenantInfo()).thenReturn(info); + + assertNotNull(this.sut.getTenantInfo()); + assertEquals("tenant1", this.sut.getTenantInfo().getName()); + } + + @Test(expected = AppException.class) + public void should_throwException_given_invalidAccountId() { + + when(this.info.getName()).thenReturn("tenant2"); + when(tenantFactory.getTenantInfo("tenant1")).thenReturn(null); + + when(this.sut.getTenantInfo()).thenReturn(info); + + assertNotNull(this.sut.getTenantInfo()); + } +} \ No newline at end of file diff --git a/indexer-service-gcp/src/test/java/org/opendes/indexer/util/ServiceAccountJwtGcpClientImplTest.java b/indexer-service-gcp/src/test/java/org/opendes/indexer/util/ServiceAccountJwtGcpClientImplTest.java index 394aa71562493df205ad0737f659f24a8bede694..697887e0fb54fb89c64ad829d819c431dbe21cfa 100644 --- a/indexer-service-gcp/src/test/java/org/opendes/indexer/util/ServiceAccountJwtGcpClientImplTest.java +++ b/indexer-service-gcp/src/test/java/org/opendes/indexer/util/ServiceAccountJwtGcpClientImplTest.java @@ -38,9 +38,9 @@ import org.opendes.core.cache.JwtCache; import org.opendes.core.logging.JaxRsDpsLog; import org.opendes.core.model.DeploymentEnvironment; import org.opendes.core.model.IdToken; -import org.opendes.core.service.TenantInfoServiceImpl; import org.opendes.core.util.AppException; import org.opendes.core.util.Config; +import org.opendes.indexer.service.TenantInfoServiceImpl; import org.powermock.core.classloader.annotations.PrepareForTest; import org.springframework.test.context.junit4.SpringRunner;