diff --git a/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/cache/Keys.groovy b/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/cache/Keys.groovy index 968281b1d78..c206cf0244b 100644 --- a/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/cache/Keys.groovy +++ b/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/cache/Keys.groovy @@ -24,6 +24,7 @@ import groovy.util.logging.Slf4j class Keys { static enum Namespace { APPLICATIONS, + PLATFORM_APPLICATIONS, CLUSTERS, SERVER_GROUPS, INSTANCES, @@ -60,6 +61,9 @@ class Keys { case Namespace.APPLICATIONS.ns: result << [application: parts[2]] break + case Namespace.PLATFORM_APPLICATIONS.ns: + result << [project: parts[2]] + break case Namespace.CLUSTERS.ns: def names = Names.parseName(parts[4]) result << [ @@ -110,6 +114,10 @@ class Keys { "$AppengineCloudProvider.ID:${Namespace.APPLICATIONS}:${application}" } + static String getPlatformApplicationKey(String project) { + "$AppengineCloudProvider.ID:${Namespace.PLATFORM_APPLICATIONS}:${project}" + } + static String getClusterKey(String account, String application, String clusterName) { "$AppengineCloudProvider.ID:${Namespace.CLUSTERS}:${account}:${application}:${clusterName}" } diff --git a/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/model/AppenginePlatformApplication.groovy b/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/model/AppenginePlatformApplication.groovy new file mode 100644 index 00000000000..21ee1ee90aa --- /dev/null +++ b/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/model/AppenginePlatformApplication.groovy @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Google, 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.clouddriver.appengine.model + +import com.google.api.services.appengine.v1.model.Application +import groovy.transform.TupleConstructor + +class AppenginePlatformApplication { + List dispatchRules + String authDomain + String codeBucket + String defaultBucket + String defaultCookieExpiration + String defaultHostname + String id + String locationId + + AppenginePlatformApplication(Application application) { + this.dispatchRules = application.getDispatchRules()?.collect { rule -> + new AppengineDispatchRule(rule.getDomain(), rule.getPath(), rule.getService()) + } ?: [] + this.authDomain = application.getAuthDomain() + this.codeBucket = application.getCodeBucket() + this.defaultBucket = application.getDefaultBucket() + this.defaultCookieExpiration = application.getDefaultCookieExpiration() + this.defaultHostname = application.getDefaultHostname() + this.id = application.getId() + this.locationId = application.getLocationId() + } + + @TupleConstructor + static class AppengineDispatchRule { + String domain + String path + String service + } +} diff --git a/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/provider/agent/AppenginePlatformApplicationCachingAgent.groovy b/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/provider/agent/AppenginePlatformApplicationCachingAgent.groovy new file mode 100644 index 00000000000..0daabaf4f41 --- /dev/null +++ b/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/provider/agent/AppenginePlatformApplicationCachingAgent.groovy @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Google, 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.clouddriver.appengine.provider.agent + +import com.fasterxml.jackson.databind.ObjectMapper +import com.google.api.services.appengine.v1.model.Application +import com.netflix.spinnaker.cats.agent.AgentDataType +import com.netflix.spinnaker.cats.agent.CacheResult +import com.netflix.spinnaker.cats.agent.DefaultCacheResult +import com.netflix.spinnaker.cats.provider.ProviderCache +import com.netflix.spinnaker.clouddriver.appengine.cache.Keys +import com.netflix.spinnaker.clouddriver.appengine.model.AppenginePlatformApplication +import com.netflix.spinnaker.clouddriver.appengine.security.AppengineNamedAccountCredentials +import com.netflix.spinnaker.clouddriver.kubernetes.provider.view.MutableCacheData +import groovy.util.logging.Slf4j + +import static com.netflix.spinnaker.cats.agent.AgentDataType.Authority.AUTHORITATIVE + +@Slf4j +class AppenginePlatformApplicationCachingAgent extends AbstractAppengineCachingAgent { + String agentType = "${accountName}/${AppenginePlatformApplicationCachingAgent.simpleName}" + + static final Set types = Collections.unmodifiableSet([ + AUTHORITATIVE.forType(Keys.Namespace.PLATFORM_APPLICATIONS.ns)] as Set + ) + + AppenginePlatformApplicationCachingAgent(String accountName, + AppengineNamedAccountCredentials credentials, + ObjectMapper objectMapper) { + super(accountName, objectMapper, credentials) + } + + @Override + String getSimpleName() { + AppenginePlatformApplicationCachingAgent.simpleName + } + + @Override + Collection getProvidedDataTypes() { + types + } + + @Override + CacheResult loadData(ProviderCache providerCache) { + def platformApplicationName = credentials.project + Application platformApplication = credentials.appengine.apps().get(platformApplicationName).execute() + Map cachedPlatformApplications = MutableCacheData.mutableCacheMap() + def apiApplicationKey = Keys.getPlatformApplicationKey(platformApplicationName) + + cachedPlatformApplications[apiApplicationKey].with { + attributes.name = platformApplicationName + attributes.platformApplication = new AppenginePlatformApplication(platformApplication) + } + + log.info("Caching ${cachedPlatformApplications.size()} platform applications in ${agentType}") + return new DefaultCacheResult([(Keys.Namespace.PLATFORM_APPLICATIONS.ns): cachedPlatformApplications.values()], [:]) + } +} diff --git a/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/provider/config/AppengineProviderConfig.groovy b/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/provider/config/AppengineProviderConfig.groovy index b8962d26a48..3e5c77f616b 100644 --- a/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/provider/config/AppengineProviderConfig.groovy +++ b/clouddriver-appengine/src/main/groovy/com/netflix/spinnaker/clouddriver/appengine/provider/config/AppengineProviderConfig.groovy @@ -21,9 +21,9 @@ import com.fasterxml.jackson.databind.SerializationFeature import com.netflix.spectator.api.Registry import com.netflix.spinnaker.cats.agent.Agent import com.netflix.spinnaker.cats.provider.ProviderSynchronizerTypeWrapper -import com.netflix.spinnaker.cats.thread.NamedThreadFactory import com.netflix.spinnaker.clouddriver.appengine.AppengineCloudProvider import com.netflix.spinnaker.clouddriver.appengine.provider.AppengineProvider +import com.netflix.spinnaker.clouddriver.appengine.provider.agent.AppenginePlatformApplicationCachingAgent import com.netflix.spinnaker.clouddriver.appengine.provider.agent.AppengineLoadBalancerCachingAgent import com.netflix.spinnaker.clouddriver.appengine.provider.agent.AppengineServerGroupCachingAgent import com.netflix.spinnaker.clouddriver.appengine.security.AppengineNamedAccountCredentials @@ -36,9 +36,6 @@ import org.springframework.context.annotation.DependsOn import org.springframework.context.annotation.Scope import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.Executors -import java.util.concurrent.ScheduledExecutorService -import java.util.concurrent.TimeUnit @Configuration class AppengineProviderConfig { @@ -96,6 +93,10 @@ class AppengineProviderConfig { credentials, objectMapper, registry) + + newlyAddedAgents << new AppenginePlatformApplicationCachingAgent(credentials.name, + credentials, + objectMapper) } }