diff --git a/gate-core/src/main/groovy/com/netflix/spinnaker/gate/services/DefaultProviderLookupService.groovy b/gate-core/src/main/groovy/com/netflix/spinnaker/gate/services/DefaultProviderLookupService.groovy new file mode 100644 index 0000000000..53dda2cad3 --- /dev/null +++ b/gate-core/src/main/groovy/com/netflix/spinnaker/gate/services/DefaultProviderLookupService.groovy @@ -0,0 +1,65 @@ +/* + * Copyright 2016 Netflix, Inc. + * + * 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 com.netflix.spinnaker.gate.services + +import com.google.common.cache.CacheBuilder +import com.google.common.cache.CacheLoader +import com.google.common.cache.LoadingCache +import com.google.common.util.concurrent.UncheckedExecutionException +import com.netflix.spinnaker.gate.services.internal.ClouddriverService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component + +import java.util.concurrent.ExecutionException +import java.util.concurrent.TimeUnit + +/** + * DefaultProviderLookupService. + */ +@Component("providerLookupService") +class DefaultProviderLookupService implements ProviderLookupService { + + private static final String FALLBACK = "unknown" + private static final String ACCOUNTS_KEY = "all" + + private final ClouddriverService clouddriverService + + private final LoadingCache> accountsCache = CacheBuilder.newBuilder() + .initialCapacity(1) + .maximumSize(1) + .refreshAfterWrite(5, TimeUnit.SECONDS) + .build(new CacheLoader>() { + @Override + List load(String key) throws Exception { + return clouddriverService.accounts + } + }) + + @Autowired + public DefaultProviderLookupService(ClouddriverService clouddriverService) { + this.clouddriverService = clouddriverService + } + + public String providerForAccount(String account) { + try { + return accountsCache.get(ACCOUNTS_KEY)?.find { it.name == account }?.type ?: FALLBACK + } catch (ExecutionException | UncheckedExecutionException ex) { + return FALLBACK + } + } + +} diff --git a/gate-core/src/main/groovy/com/netflix/spinnaker/gate/services/ProviderLookupService.groovy b/gate-core/src/main/groovy/com/netflix/spinnaker/gate/services/ProviderLookupService.groovy new file mode 100644 index 0000000000..32b4794354 --- /dev/null +++ b/gate-core/src/main/groovy/com/netflix/spinnaker/gate/services/ProviderLookupService.groovy @@ -0,0 +1,21 @@ +/* + * Copyright 2016 Netflix, Inc. + * + * 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 com.netflix.spinnaker.gate.services + +interface ProviderLookupService { + String providerForAccount(String account) +} diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ClusterService.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ClusterService.groovy index f19c2d2141..24385fa1b1 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ClusterService.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ClusterService.groovy @@ -35,6 +35,9 @@ class ClusterService { @Autowired ClouddriverService clouddriverService + @Autowired + ProviderLookupService providerLookupService + Map getClusters(String app) { HystrixFactory.newMapCommand(GROUP, "getClustersForApplication") { clouddriverService.getClusters(app) @@ -42,13 +45,13 @@ class ClusterService { } List getClustersForAccount(String app, String account) { - HystrixFactory.newListCommand(GROUP, "getClustersForApplicationInAccount") { + HystrixFactory.newListCommand(GROUP, "getClustersForApplicationInAccount-${providerLookupService.providerForAccount(account)}") { clouddriverService.getClustersForAccount(app, account) } execute() } Map getCluster(String app, String account, String clusterName) { - HystrixFactory.newMapCommand(GROUP, "getCluster") { + HystrixFactory.newMapCommand(GROUP, "getCluster-${providerLookupService.providerForAccount(account)}") { try { clouddriverService.getCluster(app, account, clusterName)?.getAt(0) as Map } catch (RetrofitError e) { @@ -66,13 +69,13 @@ class ClusterService { } List getScalingActivities(String app, String account, String clusterName, String serverGroupName, String provider, String region) { - HystrixFactory.newListCommand(GROUP, "getScalingActivitiesForCluster") { + HystrixFactory.newListCommand(GROUP, "getScalingActivitiesForCluster-${providerLookupService.providerForAccount(account)}") { clouddriverService.getScalingActivities(app, account, clusterName, provider, serverGroupName, region) } execute() } Map getTargetServerGroup(String app, String account, String clusterName, String cloudProviderType, String scope, String target, Boolean onlyEnabled, Boolean validateOldest) { - HystrixFactory.newMapCommand(GROUP, "getTargetServerGroup") { + HystrixFactory.newMapCommand(GROUP, "getTargetServerGroup-${providerLookupService.providerForAccount(account)}") { try { return clouddriverService.getTargetServerGroup(app, account, clusterName, cloudProviderType, scope, target, onlyEnabled, validateOldest) } catch (RetrofitError re) { diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ImageService.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ImageService.groovy index dfaf3c1c0a..38aed7e660 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ImageService.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ImageService.groovy @@ -31,14 +31,17 @@ class ImageService { @Autowired ClouddriverService clouddriverService + @Autowired + ProviderLookupService providerLookupService + List getForAccountAndRegion(String provider, String account, String region, String imageId) { - HystrixFactory.newListCommand(GROUP, "getImagesForAccountAndRegion") { + HystrixFactory.newListCommand(GROUP, "getImagesForAccountAndRegion-${providerLookupService.providerForAccount(account)}") { clouddriverService.getImageDetails(provider, account, region, imageId) } execute() } List search(String provider, String query, String region, String account) { - HystrixFactory.newListCommand(GROUP, "searchImages") { + HystrixFactory.newListCommand(GROUP, "searchImages-${providerLookupService.providerForAccount(account)}") { clouddriverService.findImages(provider, query, region, account) } execute() } diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/InstanceService.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/InstanceService.groovy index d255dd891f..9f6fdb4814 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/InstanceService.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/InstanceService.groovy @@ -35,8 +35,11 @@ class InstanceService { @Autowired InsightConfiguration insightConfiguration + @Autowired + ProviderLookupService providerLookupService + Map getForAccountAndRegion(String account, String region, String instanceId) { - HystrixFactory.newMapCommand(GROUP, "getInstancesForAccountAndRegion") { + HystrixFactory.newMapCommand(GROUP, "getInstancesForAccountAndRegion-${providerLookupService.providerForAccount(account)}") { def instanceDetails = clouddriverService.getInstanceDetails(account, region, instanceId) def instanceContext = instanceDetails.collectEntries { return it.value instanceof String ? [it.key, it.value] : [it.key, ""] @@ -50,7 +53,7 @@ class InstanceService { } Map getConsoleOutput(String account, String region, String instanceId, String provider) { - HystrixFactory.newMapCommand(GROUP, "getConsoleOutput") { + HystrixFactory.newMapCommand(GROUP, "getConsoleOutput-${providerLookupService.providerForAccount(account)}") { return clouddriverService.getConsoleOutput(account, region, instanceId, provider) } execute() } diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/JobService.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/JobService.groovy index ba087d9f19..f35394c029 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/JobService.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/JobService.groovy @@ -35,6 +35,9 @@ class JobService { @Autowired InsightConfiguration insightConfiguration + @Autowired + ProviderLookupService providerLookupService + List getForApplication(String applicationName, String expand) { String commandKey = Boolean.valueOf(expand) ? "getExpandedJobsForApplication" : "getJobsForApplication" HystrixFactory.newListCommand(GROUP, commandKey) { @@ -43,7 +46,7 @@ class JobService { } Map getForApplicationAndAccountAndRegion(String applicationName, String account, String region, String name) { - HystrixFactory.newMapCommand(GROUP, "getJobsForApplicationAccountAndRegion", { + HystrixFactory.newMapCommand(GROUP, "getJobsForApplicationAccountAndRegion-${providerLookupService.providerForAccount(account)}", { try { def context = getContext(applicationName, account, region, name) return clouddriverService.getJobDetails(applicationName, account, region, name) + [ diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/LoadBalancerService.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/LoadBalancerService.groovy index 5f781263ea..326fb7bf08 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/LoadBalancerService.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/LoadBalancerService.groovy @@ -31,26 +31,26 @@ class LoadBalancerService { ClouddriverService clouddriverService List getAll(String provider = "aws") { - HystrixFactory.newListCommand(GROUP, "getAllLoadBalancersForProvider") { + HystrixFactory.newListCommand(GROUP, "getAllLoadBalancersForProvider-$provider") { clouddriverService.getLoadBalancers(provider) } execute() } Map get(String name, String provider = "aws") { - HystrixFactory.newMapCommand(GROUP, "getLoadBalancer") { + HystrixFactory.newMapCommand(GROUP, "getLoadBalancer-$provider") { clouddriverService.getLoadBalancer(provider, name) } execute() } List getDetailsForAccountAndRegion(String account, String region, String name, String provider = "aws") { - HystrixFactory.newListCommand(GROUP, "getLoadBalancerDetails") { + HystrixFactory.newListCommand(GROUP, "getLoadBalancerDetails-$provider") { clouddriverService.getLoadBalancerDetails(provider, account, region, name) } execute() } List getClusterLoadBalancers(String appName, String account, String provider, String clusterName) { HystrixFactory.newListCommand(GROUP, - "getClusterLoadBalancers") { + "getClusterLoadBalancers-$provider") { clouddriverService.getClusterLoadBalancers(appName, account, clusterName, provider) } execute() } diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/NetworkService.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/NetworkService.groovy index 4eae191669..a3b2c20c06 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/NetworkService.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/NetworkService.groovy @@ -43,7 +43,7 @@ class NetworkService { } List getNetworks(String cloudProvider) { - command("networks") { + command("networks-$cloudProvider") { clouddriverService.getNetworks(cloudProvider) } execute() } diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/SecurityGroupService.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/SecurityGroupService.groovy index 122d684e68..11598cf2e1 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/SecurityGroupService.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/SecurityGroupService.groovy @@ -75,7 +75,7 @@ class SecurityGroupService { * @param region optional. nullable */ Map getForAccountAndProviderAndRegion(String account, String provider, String region) { - HystrixFactory.newMapCommand(GROUP, "getSecurityGroupsForAccountAndProvider") { + HystrixFactory.newMapCommand(GROUP, "getSecurityGroupsForAccountAndProvider-$provider") { clouddriverService.getSecurityGroups(account, provider, region) } execute() } @@ -87,7 +87,7 @@ class SecurityGroupService { * @param region optional. nullable */ Map getSecurityGroup(String account, String provider, String name, String region, String vpcId = null) { - HystrixFactory.newMapCommand(GROUP, "getSecurityGroupByIdentifiers") { + HystrixFactory.newMapCommand(GROUP, "getSecurityGroupByIdentifiers-$provider") { clouddriverService.getSecurityGroup(account, provider, name, region, vpcId) } execute() } diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ServerGroupService.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ServerGroupService.groovy index 18ccbed16f..8bdd064472 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ServerGroupService.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/services/ServerGroupService.groovy @@ -36,6 +36,9 @@ class ServerGroupService { @Autowired InsightConfiguration insightConfiguration + @Autowired + ProviderLookupService providerLookupService + List getForApplication(String applicationName, String expand) { String commandKey = Boolean.valueOf(expand) ? "getExpandedServerGroupsForApplication" : "getServerGroupsForApplication" HystrixFactory.newListCommand(GROUP, commandKey) { @@ -44,7 +47,7 @@ class ServerGroupService { } Map getForApplicationAndAccountAndRegion(String applicationName, String account, String region, String serverGroupName) { - HystrixFactory.newMapCommand(GROUP, "getServerGroupsForApplicationAccountAndRegion") { + HystrixFactory.newMapCommand(GROUP, "getServerGroupsForApplicationAccountAndRegion-${providerLookupService.providerForAccount(account)}") { try { def context = getContext(applicationName, account, region, serverGroupName) return clouddriverService.getServerGroupDetails(applicationName, account, region, serverGroupName) + [ diff --git a/gate-web/src/test/groovy/com/netflix/spinnaker/gate/services/InstanceServiceSpec.groovy b/gate-web/src/test/groovy/com/netflix/spinnaker/gate/services/InstanceServiceSpec.groovy index aa9e36cf83..ca51cb46d0 100644 --- a/gate-web/src/test/groovy/com/netflix/spinnaker/gate/services/InstanceServiceSpec.groovy +++ b/gate-web/src/test/groovy/com/netflix/spinnaker/gate/services/InstanceServiceSpec.groovy @@ -28,6 +28,9 @@ class InstanceServiceSpec extends Specification { clouddriverService: Mock(ClouddriverService) { 1 * getInstanceDetails(_, _, _) >> { return [privateIpAddress: "10.0.0.1", map: [:]] } }, + providerLookupService: Stub(ProviderLookupService) { + providerForAccount(_) >> "test" + }, insightConfiguration: new InsightConfiguration( instance: [new InsightConfiguration.Link(url: '${account}-${region}-${instanceId}-{DNE}-${privateIpAddress}')] ) diff --git a/gate-web/src/test/groovy/com/netflix/spinnaker/gate/services/ServerGroupServiceSpec.groovy b/gate-web/src/test/groovy/com/netflix/spinnaker/gate/services/ServerGroupServiceSpec.groovy index d20383c18f..23e999b241 100644 --- a/gate-web/src/test/groovy/com/netflix/spinnaker/gate/services/ServerGroupServiceSpec.groovy +++ b/gate-web/src/test/groovy/com/netflix/spinnaker/gate/services/ServerGroupServiceSpec.groovy @@ -28,6 +28,9 @@ class ServerGroupServiceSpec extends Specification { clouddriverService: Mock(ClouddriverService) { 1 * getServerGroupDetails(_, _, _, _) >> { return [:] } }, + providerLookupService: Stub(ProviderLookupService) { + providerForAccount(_) >> "test" + }, insightConfiguration: new InsightConfiguration( serverGroup: [new InsightConfiguration.Link(url: '${application}-${account}-${region}-${serverGroup}-{DNE}')] )