Skip to content

Commit

Permalink
Update EcsApplicationProvider to use EcsApplicationCacheClient
Browse files Browse the repository at this point in the history
  • Loading branch information
piradeepk committed Feb 23, 2021
1 parent 76dfc3c commit db79103
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,101 @@

package com.netflix.spinnaker.clouddriver.ecs.cache.client;

import static com.netflix.spinnaker.clouddriver.ecs.EcsCloudProvider.ID;
import static com.netflix.spinnaker.clouddriver.ecs.cache.Keys.Namespace.APPLICATIONS;
import static com.netflix.spinnaker.clouddriver.ecs.cache.Keys.Namespace.SERVICES;
import static java.util.stream.Collectors.toSet;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.spinnaker.cats.cache.Cache;
import com.netflix.spinnaker.cats.cache.CacheData;
import com.netflix.spinnaker.clouddriver.ecs.cache.model.Application;
import com.netflix.spinnaker.cats.cache.RelationshipCacheFilter;
import com.netflix.spinnaker.clouddriver.ecs.cache.Keys;
import com.netflix.spinnaker.clouddriver.ecs.model.EcsApplication;
import com.netflix.spinnaker.clouddriver.model.Application;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class ApplicationCacheClient extends AbstractCacheClient<Application> {
private ObjectMapper objectMapper;

@Autowired
public ApplicationCacheClient(Cache cacheView, ObjectMapper objectMapper) {
public ApplicationCacheClient(Cache cacheView) {
super(cacheView, APPLICATIONS.toString());
this.objectMapper = objectMapper;
}

@Override
protected Application convert(CacheData cacheData) {
Application application = new Application();
Map<String, Object> attributes = cacheData.getAttributes();
log.debug("Translating CacheData to EcsApplication");
if (cacheData == null) {
return null;
}

application.setName((String) attributes.get("name"));
String appName = (String) cacheData.getAttributes().get("name");

Map<String, String> attributes = new HashMap<>();
attributes.put("name", appName);

Map<String, Set<String>> clusterNames = new HashMap<>();

EcsApplication application = new EcsApplication(appName, attributes, clusterNames);

Set<String> services = getServiceRelationships(cacheData);
log.info("Found {} services for app {}", services.size(), appName);
services.forEach(
key -> {
Map<String, String> parsedKey = Keys.parse(key);
if (application.getClusterNames().get(parsedKey.get("account")) != null) {
application
.getClusterNames()
.get(parsedKey.get("account"))
.add(parsedKey.get("serviceName"));
} else {
application
.getClusterNames()
.put(
parsedKey.get("account"),
new HashSet<>(Arrays.asList(parsedKey.get("serviceName"))));
}
});

log.info(
"Found {} clusterNames for application {}", application.getClusterNames(), application);
return application;
}

public Application getApplication(String name) {
return convert(
cacheView.get(
APPLICATIONS.ns,
Keys.getApplicationKey(name),
RelationshipCacheFilter.include(SERVICES.ns)));
}

public Set<Application> getApplications(boolean expand) {
RelationshipCacheFilter relationshipFilter =
expand ? RelationshipCacheFilter.include(SERVICES.ns) : RelationshipCacheFilter.none();
Collection<CacheData> applications =
cacheView.getAll(
APPLICATIONS.ns,
cacheView.filterIdentifiers(APPLICATIONS.ns, ID + ";*"),
relationshipFilter);
log.info("getApplications found {} Spinnaker applications in the cache.", applications.size());
return applications.stream().map(this::convert).collect(toSet());
}

private Set<String> getServiceRelationships(CacheData cacheData) {
Collection<String> serviceRelationships = cacheData.getRelationships().get(SERVICES.ns);
return serviceRelationships == null
? Collections.emptySet()
: new HashSet<>(serviceRelationships);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ protected List<Application> getItems(AmazonECS ecs, ProviderCache providerCache)
updateApplicationRelationships(appRelationships, applicationKey, serviceKey)
.get(applicationKey));

log.info(
log.debug(
"ECS application "
+ applicationKey
+ " with "
Expand Down Expand Up @@ -140,7 +140,7 @@ private Map<String, Map<String, Collection<String>>> updateApplicationRelationsh
String serviceKey) {
Map<String, Collection<String>> existingAppRelation = appRelationships.get(applicationKey);
if (existingAppRelation != null && existingAppRelation.size() > 0) {
log.info("Updating existing application relation for " + applicationKey);
log.debug("Updating existing application relation for " + applicationKey);

Collection<String> serviceRelationship = existingAppRelation.get(SERVICES.ns);
if (serviceRelationship != null && !serviceRelationship.isEmpty()) {
Expand All @@ -150,7 +150,7 @@ private Map<String, Map<String, Collection<String>>> updateApplicationRelationsh
}
existingAppRelation.put(SERVICES.ns, serviceRelationship);
} else {
log.info("Creating new application relation for " + applicationKey);
log.debug("Creating new application relation for " + applicationKey);

existingAppRelation = new HashMap<String, Collection<String>>();
existingAppRelation.put(SERVICES.ns, Sets.newHashSet(serviceKey));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,111 +15,30 @@

package com.netflix.spinnaker.clouddriver.ecs.view;

import static com.netflix.spinnaker.clouddriver.ecs.EcsCloudProvider.ID;
import static com.netflix.spinnaker.clouddriver.ecs.cache.Keys.Namespace.APPLICATIONS;
import static com.netflix.spinnaker.clouddriver.ecs.cache.Keys.Namespace.SERVICES;
import static java.util.stream.Collectors.toSet;

import com.netflix.spinnaker.cats.cache.Cache;
import com.netflix.spinnaker.cats.cache.CacheData;
import com.netflix.spinnaker.cats.cache.RelationshipCacheFilter;
import com.netflix.spinnaker.clouddriver.ecs.cache.Keys;
import com.netflix.spinnaker.clouddriver.ecs.model.EcsApplication;
import com.netflix.spinnaker.clouddriver.ecs.cache.client.ApplicationCacheClient;
import com.netflix.spinnaker.clouddriver.model.Application;
import com.netflix.spinnaker.clouddriver.model.ApplicationProvider;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class EcsApplicationProvider implements ApplicationProvider {

private final Cache cacheView;
private final ApplicationCacheClient cacheClient;

@Autowired
public EcsApplicationProvider(Cache cacheView) {
this.cacheView = cacheView;
public EcsApplicationProvider(ApplicationCacheClient cacheClient) {
this.cacheClient = cacheClient;
}

@Override
public Application getApplication(String name) {
return translate(
cacheView.get(
APPLICATIONS.ns,
Keys.getApplicationKey(name),
RelationshipCacheFilter.include(SERVICES.ns)));
return cacheClient.getApplication(name);
}

@Override
public Set<Application> getApplications(boolean expand) {
RelationshipCacheFilter relationshipFilter =
expand ? RelationshipCacheFilter.include(SERVICES.ns) : RelationshipCacheFilter.none();
Collection<CacheData> applications =
cacheView.getAll(
APPLICATIONS.ns,
cacheView.filterIdentifiers(APPLICATIONS.ns, ID + ";*"),
relationshipFilter);
log.info("getApplications found {} Spinnaker applications in the cache.", applications.size());
return applications.stream().map(this::translate).collect(toSet());
}

private Application translate(CacheData cacheData) {
log.debug("Translating CacheData to EcsApplication");
if (cacheData == null) {
HashMap<String, String> attributes = new HashMap<>();
HashMap<String, Set<String>> clusterNames = new HashMap<>();
EcsApplication application = new EcsApplication("test", attributes, clusterNames);
return application;
}

String appName = (String) cacheData.getAttributes().get("name");

HashMap<String, String> attributes = new HashMap<>();
attributes.put("name", appName);

HashMap<String, Set<String>> clusterNames = new HashMap<>();

EcsApplication application = new EcsApplication(appName, attributes, clusterNames);
if (application == null) {
return null;
}

Set<String> services = getServiceRelationships(cacheData);
log.info("Found {} services for app {}", services.size(), appName);
services.forEach(
key -> {
Map<String, String> parsedKey = Keys.parse(key);
if (application.getClusterNames().get(parsedKey.get("account")) != null) {
application
.getClusterNames()
.get(parsedKey.get("account"))
.add(parsedKey.get("serviceName"));
} else {
application
.getClusterNames()
.put(
parsedKey.get("account"),
new HashSet<>(Arrays.asList(parsedKey.get("serviceName"))));
}
});

log.info(
"Found {} clusterNames for application {}", application.getClusterNames(), application);
return application;
}

private Set<String> getServiceRelationships(CacheData cacheData) {
Collection<String> serviceRelationships = cacheData.getRelationships().get(SERVICES.ns);
return serviceRelationships == null
? Collections.emptySet()
: new HashSet<>(serviceRelationships);
return cacheClient.getApplications(expand);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.amazonaws.services.ecs.model.Service
import com.netflix.spinnaker.cats.cache.Cache
import com.netflix.spinnaker.cats.cache.DefaultCacheData
import com.netflix.spinnaker.clouddriver.ecs.TestCredential
import com.netflix.spinnaker.clouddriver.ecs.cache.client.ApplicationCacheClient
import com.netflix.spinnaker.clouddriver.ecs.cache.Keys
import com.netflix.spinnaker.clouddriver.ecs.model.EcsApplication
import com.netflix.spinnaker.clouddriver.ecs.provider.agent.TestServiceCachingAgentFactory
Expand All @@ -31,8 +32,9 @@ import spock.lang.Subject

class EcsApplicationProviderSpec extends Specification {
def cache = Mock(Cache)
def applicationCacheClient = new ApplicationCacheClient(cache)
@Subject
def provider = new EcsApplicationProvider(cache)
def provider = new EcsApplicationProvider(applicationCacheClient)

def 'should return an application'() {
given:
Expand Down
Loading

0 comments on commit db79103

Please sign in to comment.