Skip to content

Commit

Permalink
First pass at:
Browse files Browse the repository at this point in the history
  - GCS configuration
  - /fetch controller will synchronously dump retrieved metrics verbatim into a bucket (still placeholder logic)
  • Loading branch information
duftler committed Mar 1, 2017
1 parent 57c732a commit d152a42
Show file tree
Hide file tree
Showing 25 changed files with 489 additions and 64 deletions.
1 change: 1 addition & 0 deletions kayenta-core/kayenta-core.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
dependencies {
compile spinnaker.dependency('bootWeb')
compile spinnaker.dependency('lombok')
spinnaker.group('jackson')
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.netflix.spinnaker.kayenta.metrics.MetricsServiceRepository;
import com.netflix.spinnaker.kayenta.security.AccountCredentialsRepository;
import com.netflix.spinnaker.kayenta.security.MapBackedAccountCredentialsRepository;
import com.netflix.spinnaker.kayenta.storage.MapBackedStorageServiceRepository;
import com.netflix.spinnaker.kayenta.storage.StorageServiceRepository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;

Expand All @@ -36,4 +38,10 @@ AccountCredentialsRepository accountCredentialsRepository() {
MetricsServiceRepository metricsServiceRepository() {
return new MapBackedMetricsServiceRepository();
}

@Bean
@ConditionalOnMissingBean(StorageServiceRepository.class)
StorageServiceRepository storageServiceRepository() {
return new MapBackedStorageServiceRepository();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,20 @@

import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

public class MapBackedMetricsServiceRepository implements MetricsServiceRepository {

@Autowired
List<MetricsService> metricsServices;
@Autowired(required = false)
List<MetricsService> metricsServices = Collections.emptyList();

@Override
public MetricsService getOne(String accountName) {
for (MetricsService metricsService : metricsServices) {
if (metricsService.servicesAccount(accountName)) {
return metricsService;
}
}

return null;
public Optional<MetricsService> getOne(String accountName) {
return metricsServices
.stream()
.filter(m -> m.servicesAccount(accountName))
.findFirst();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@

import java.io.IOException;
import java.util.Map;
import java.util.Optional;

public interface MetricsService {
boolean servicesAccount(String accountName);
Map queryMetrics(String accountName,
String instanceNamePrefix,
String intervalStartTime,
String intervalEndTime) throws IOException;
Optional<Map> queryMetrics(String accountName,
String instanceNamePrefix,
String intervalStartTime,
String intervalEndTime) throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.netflix.spinnaker.kayenta.metrics;

import java.util.Optional;

public interface MetricsServiceRepository {
MetricsService getOne(String accountName);
Optional<MetricsService> getOne(String accountName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@

package com.netflix.spinnaker.kayenta.security;

import java.util.Optional;
import java.util.Set;

public interface AccountCredentialsRepository {
AccountCredentials getOne(String name);
Optional<AccountCredentials> getOne(String accountName);

AccountCredentials getOne(AccountCredentials.Type credentialsType);
Optional<AccountCredentials> getOne(AccountCredentials.Type credentialsType);

Set<? extends AccountCredentials> getAll();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,35 @@

import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class MapBackedAccountCredentialsRepository implements AccountCredentialsRepository {

private final Map<String, AccountCredentials> map = new ConcurrentHashMap<>();
private final Map<String, AccountCredentials> accountNameToCredentialsMap = new ConcurrentHashMap<>();

@Override
public AccountCredentials getOne(String name) {
return map.get(name);
public Optional<AccountCredentials> getOne(String accountName) {
return Optional.ofNullable(accountNameToCredentialsMap.get(accountName));
}

@Override
public AccountCredentials getOne(AccountCredentials.Type credentialsType) {
for (AccountCredentials accountCredentials : map.values()) {
if (accountCredentials.getSupportedTypes().contains(credentialsType)) {
return accountCredentials;
}
}

return null;
public Optional<AccountCredentials> getOne(AccountCredentials.Type credentialsType) {
return accountNameToCredentialsMap
.values()
.stream()
.filter(a -> a.getSupportedTypes().contains(credentialsType))
.findFirst();
}

@Override
public Set<AccountCredentials> getAll() {
return new HashSet<>(map.values());
return new HashSet<>(accountNameToCredentialsMap.values());
}

@Override
public AccountCredentials save(String name, AccountCredentials credentials) {
return map.put(credentials.getName(), credentials);
return accountNameToCredentialsMap.put(credentials.getName(), credentials);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.kayenta.storage;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

public class MapBackedStorageServiceRepository implements StorageServiceRepository {

@Autowired(required = false)
List<StorageService> storageServices = Collections.emptyList();

@Override
public Optional<StorageService> getOne(String accountName) {
return storageServices
.stream()
.filter(s -> s.servicesAccount(accountName))
.findFirst();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.kayenta.storage;

import lombok.Getter;

public enum ObjectType {
METRICS("metrics", "metrics.json");

@Getter
final String group;

@Getter
final String defaultMetadataFilename;

ObjectType(String group, String defaultMetadataFilename) {
this.group = group;
this.defaultMetadataFilename = defaultMetadataFilename;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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.kayenta.storage;

import java.io.IOException;
import java.util.Map;

public interface StorageService {
boolean servicesAccount(String accountName);
<T> void storeObject(String accountName, ObjectType objectType, String objectKey, T obj);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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.kayenta.storage;

import java.util.Optional;

public interface StorageServiceRepository {
Optional<StorageService> getOne(String accountName);
}
7 changes: 7 additions & 0 deletions kayenta-gcs/kayenta-gcs.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dependencies {
compile project(":kayenta-core")
compile project(":kayenta-google")
compile spinnaker.dependency('bootWeb')
compile spinnaker.dependency('lombok')
spinnaker.group('google')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* 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.kayenta.gcs.config;

import com.netflix.spinnaker.kayenta.gcs.storage.GcsStorageService;
import com.netflix.spinnaker.kayenta.google.security.GoogleNamedAccountCredentials;
import com.netflix.spinnaker.kayenta.security.AccountCredentials;
import com.netflix.spinnaker.kayenta.security.AccountCredentialsRepository;
import com.netflix.spinnaker.kayenta.storage.StorageService;
import com.netflix.spinnaker.kayenta.storage.StorageServiceRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

@Configuration
@EnableConfigurationProperties
@ConditionalOnProperty("kayenta.gcs.enabled")
@ComponentScan({"com.netflix.spinnaker.kayenta.gcs"})
@Slf4j
public class GcsConfiguration {

@Bean
@DependsOn({"registerGoogleCredentials"})
public StorageService storageService(AccountCredentialsRepository accountCredentialsRepository) {
GcsStorageService.GcsStorageServiceBuilder gcsStorageServiceBuilder = GcsStorageService.builder();

for (AccountCredentials accountCredentials : accountCredentialsRepository.getAll()) {
if (accountCredentials instanceof GoogleNamedAccountCredentials) {
GoogleNamedAccountCredentials googleNamedAccountCredentials = (GoogleNamedAccountCredentials)accountCredentials;

if (googleNamedAccountCredentials.getSupportedTypes().contains(AccountCredentials.Type.OBJECT_STORE)) {
gcsStorageServiceBuilder.accountName(googleNamedAccountCredentials.getName());
}
}
}

GcsStorageService gcsStorageService = gcsStorageServiceBuilder.build();

log.info("Populated GcsStorageService with {} Google accounts.", gcsStorageService.getAccountNames().size());

return gcsStorageService;
}
}
Loading

0 comments on commit d152a42

Please sign in to comment.