Add Influxdb 0.9.0 support

Change-Id: I30c77bc9d0c11c54e2834902d8fb7e8794a7c26f
This commit is contained in:
Deklan Dieterly 2015-02-13 16:30:51 -07:00
parent 8e73ebfda4
commit 3345f525d7
65 changed files with 1194 additions and 344 deletions

View File

@ -197,6 +197,11 @@
<version>6.8.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
</dependencies>
<build>

View File

@ -28,7 +28,7 @@ import javax.validation.Valid;
import javax.validation.constraints.NotNull;
public class MonApiConfiguration extends Configuration {
public class ApiConfig extends Configuration {
@NotEmpty
public String region;
@NotNull

View File

@ -59,13 +59,13 @@ import monasca.common.util.Injector;
/**
* Monitoring API application.
*/
public class MonApiApplication extends Application<MonApiConfiguration> {
public class MonApiApplication extends Application<ApiConfig> {
public static void main(String[] args) throws Exception {
new MonApiApplication().run(args);
}
@Override
public void initialize(Bootstrap<MonApiConfiguration> bootstrap) {
public void initialize(Bootstrap<ApiConfig> bootstrap) {
/** Configure bundles */
bootstrap.addBundle(new DBIExceptionsBundle());
}
@ -77,7 +77,7 @@ public class MonApiApplication extends Application<MonApiConfiguration> {
@Override
@SuppressWarnings("unchecked")
public void run(MonApiConfiguration config, Environment environment) throws Exception {
public void run(ApiConfig config, Environment environment) throws Exception {
/** Wire services */
Injector.registerModules(new MonApiModule(environment, config));

View File

@ -41,17 +41,17 @@ import monasca.api.infrastructure.InfrastructureModule;
* Monitoring API server bindings.
*/
public class MonApiModule extends AbstractModule {
private final MonApiConfiguration config;
private final ApiConfig config;
private final Environment environment;
public MonApiModule(Environment environment, MonApiConfiguration config) {
public MonApiModule(Environment environment, ApiConfig config) {
this.environment = environment;
this.config = config;
}
@Override
protected void configure() {
bind(MonApiConfiguration.class).toInstance(config);
bind(ApiConfig.class).toInstance(config);
bind(MetricRegistry.class).toInstance(environment.metrics());
bind(DataSourceFactory.class).annotatedWith(Names.named("mysql")).toInstance(config.mysql);
bind(DataSourceFactory.class).annotatedWith(Names.named("vertica")).toInstance(config.vertica);

View File

@ -34,7 +34,7 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Sets;
import monasca.api.MonApiConfiguration;
import monasca.api.ApiConfig;
import monasca.api.app.command.UpdateAlarmDefinitionCommand;
import monasca.common.model.event.AlarmDefinitionCreatedEvent;
import monasca.common.model.event.AlarmDefinitionDeletedEvent;
@ -47,10 +47,10 @@ import monasca.api.domain.exception.EntityExistsException;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.exception.InvalidEntityException;
import monasca.api.domain.model.alarm.Alarm;
import monasca.api.domain.model.alarm.AlarmRepository;
import monasca.api.domain.model.alarm.AlarmRepo;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepository;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepo;
import monasca.common.util.Exceptions;
import monasca.common.util.Serialization;
@ -60,17 +60,17 @@ import monasca.common.util.Serialization;
public class AlarmDefinitionService {
private static final Logger LOG = LoggerFactory.getLogger(AlarmService.class);
private final MonApiConfiguration config;
private final ApiConfig config;
private final Producer<String, String> producer;
private final AlarmDefinitionRepository repo;
private final AlarmRepository alarmRepo;
private final NotificationMethodRepository notificationMethodRepo;
private final AlarmDefinitionRepo repo;
private final AlarmRepo alarmRepo;
private final NotificationMethodRepo notificationMethodRepo;
long eventCount;
@Inject
public AlarmDefinitionService(MonApiConfiguration config, Producer<String, String> producer,
AlarmDefinitionRepository repo, AlarmRepository alarmRepo,
NotificationMethodRepository notificationMethodRepo) {
public AlarmDefinitionService(ApiConfig config, Producer<String, String> producer,
AlarmDefinitionRepo repo, AlarmRepo alarmRepo,
NotificationMethodRepo notificationMethodRepo) {
this.config = config;
this.producer = producer;
this.repo = repo;

View File

@ -23,7 +23,7 @@ import kafka.producer.KeyedMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import monasca.api.MonApiConfiguration;
import monasca.api.ApiConfig;
import monasca.api.app.command.UpdateAlarmCommand;
import monasca.common.model.event.AlarmDeletedEvent;
import monasca.common.model.event.AlarmStateTransitionedEvent;
@ -33,9 +33,9 @@ import monasca.common.model.alarm.AlarmSubExpression;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.exception.InvalidEntityException;
import monasca.api.domain.model.alarm.Alarm;
import monasca.api.domain.model.alarm.AlarmRepository;
import monasca.api.domain.model.alarm.AlarmRepo;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
import monasca.common.util.Exceptions;
import monasca.common.util.Serialization;
@ -45,15 +45,15 @@ import monasca.common.util.Serialization;
public class AlarmService {
private static final Logger LOG = LoggerFactory.getLogger(AlarmService.class);
private final MonApiConfiguration config;
private final ApiConfig config;
private final Producer<String, String> producer;
private final AlarmRepository repo;
private final AlarmDefinitionRepository alarmDefRepo;
private final AlarmRepo repo;
private final AlarmDefinitionRepo alarmDefRepo;
private long messageCount = 0;
@Inject
public AlarmService(MonApiConfiguration config, Producer<String, String> producer,
AlarmRepository repo, AlarmDefinitionRepository alarmDefRepo) {
public AlarmService(ApiConfig config, Producer<String, String> producer,
AlarmRepo repo, AlarmDefinitionRepo alarmDefRepo) {
this.config = config;
this.producer = producer;
this.repo = repo;

View File

@ -32,7 +32,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import monasca.api.MonApiConfiguration;
import monasca.api.ApiConfig;
import monasca.common.model.metric.Metric;
import monasca.common.model.metric.MetricEnvelope;
import monasca.common.model.metric.MetricEnvelopes;
@ -41,13 +41,13 @@ import monasca.common.model.metric.MetricEnvelopes;
* Metric service implementation.
*/
public class MetricService {
private final MonApiConfiguration config;
private final ApiConfig config;
private final Producer<String, String> producer;
private final Meter metricMeter;
private final Meter batchMeter;
@Inject
public MetricService(MonApiConfiguration config, Producer<String, String> producer,
public MetricService(ApiConfig config, Producer<String, String> producer,
MetricRegistry metricRegistry) {
this.config = config;
this.producer = producer;

View File

@ -16,8 +16,8 @@ package monasca.api.domain;
import javax.inject.Singleton;
import com.google.inject.AbstractModule;
import monasca.api.domain.model.version.VersionRepository;
import monasca.api.domain.service.impl.VersionRepositoryImpl;
import monasca.api.domain.model.version.VersionRepo;
import monasca.api.domain.service.impl.VersionRepoImpl;
/**
* Domain layer bindings.
@ -25,6 +25,6 @@ import monasca.api.domain.service.impl.VersionRepositoryImpl;
public class DomainModule extends AbstractModule {
@Override
protected void configure() {
bind(VersionRepository.class).to(VersionRepositoryImpl.class).in(Singleton.class);
bind(VersionRepo.class).to(VersionRepoImpl.class).in(Singleton.class);
}
}

View File

@ -7,7 +7,7 @@ import monasca.common.model.alarm.AlarmState;
import monasca.common.model.alarm.AlarmSubExpression;
import monasca.api.domain.exception.EntityNotFoundException;
public interface AlarmRepository {
public interface AlarmRepo {
/**
* Deletes all alarms associated with the {@code id}.
*/

View File

@ -24,7 +24,7 @@ import monasca.api.domain.exception.EntityNotFoundException;
/**
* Repository for alarm definitions.
*/
public interface AlarmDefinitionRepository {
public interface AlarmDefinitionRepo {
/**
* Creates and returns a new alarm definition for the criteria.
*/

View File

@ -24,7 +24,7 @@ import java.util.Map;
/**
* Repository for alarm state history.
*/
public interface AlarmStateHistoryRepository {
public interface AlarmStateHistoryRepo {
/**
* @throws EntityNotFoundException if an alarm cannot be found for the {@code alarmId}
*/

View File

@ -22,7 +22,7 @@ import java.util.Map;
/**
* Repository for measurements.
*/
public interface MeasurementRepository {
public interface MeasurementRepo {
/**
* Finds measurements for the given criteria.
*/

View File

@ -13,6 +13,7 @@
*/
package monasca.api.domain.model.measurement;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -37,6 +38,12 @@ public class Measurements extends AbstractEntity {
this.measurements = measurements;
}
public Measurements(String name, Map<String, String> dimensions) {
this.name = name;
this.dimensions = dimensions;
this.measurements = new LinkedList<>();
}
public void addMeasurement(Object[] measurement) {
measurements.add(measurement);
}

View File

@ -21,7 +21,7 @@ import java.util.Map;
/**
* Repository for metrics.
*/
public interface MetricDefinitionRepository {
public interface MetricDefinitionRepo {
/**
* Finds metrics for the given criteria.
*/

View File

@ -20,7 +20,7 @@ import monasca.api.domain.exception.EntityNotFoundException;
/**
* Repository for notification methods.
*/
public interface NotificationMethodRepository {
public interface NotificationMethodRepo {
NotificationMethod create(String tenantId, String name, NotificationMethodType type,
String address);

View File

@ -22,7 +22,7 @@ import java.util.Map;
/**
* Repository for statistics.
*/
public interface StatisticRepository {
public interface StatisticRepo {
/**
* Finds statistics for the given criteria.
*/

View File

@ -14,6 +14,7 @@
package monasca.api.domain.model.statistic;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -30,6 +31,14 @@ public class Statistics {
statistics = new ArrayList<>();
}
public Statistics(String name, Map<String, String> dimensions, List<String> columns) {
this.name = name;
this.dimensions = dimensions;
this.columns = columns;
this.statistics = new LinkedList<>();
}
public void addValues(List<Object> value) {
statistics.add(value);
}
@ -67,6 +76,10 @@ public class Statistics {
return true;
}
public void addStatistics(List<Object> statistics) {
this.statistics.add(statistics);
}
public List<String> getColumns() {
return columns;
}

View File

@ -20,7 +20,7 @@ import java.util.List;
/**
* Repository for versions.
*/
public interface VersionRepository {
public interface VersionRepo {
List<Version> find();
/**

View File

@ -22,12 +22,12 @@ import org.joda.time.DateTimeZone;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.version.Version;
import monasca.api.domain.model.version.Version.VersionStatus;
import monasca.api.domain.model.version.VersionRepository;
import monasca.api.domain.model.version.VersionRepo;
/**
* Version repository implementation.
*/
public class VersionRepositoryImpl implements VersionRepository {
public class VersionRepoImpl implements VersionRepo {
private static final Version v2_0 = new Version("v2.0", VersionStatus.CURRENT, new DateTime(
DateTimeZone.UTC));

View File

@ -21,65 +21,100 @@ import org.influxdb.InfluxDBFactory;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.ProvisionException;
import monasca.api.MonApiConfiguration;
import monasca.api.domain.model.alarm.AlarmRepository;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepository;
import monasca.api.domain.model.measurement.MeasurementRepository;
import monasca.api.domain.model.metric.MetricDefinitionRepository;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepository;
import monasca.api.domain.model.statistic.StatisticRepository;
import monasca.api.infrastructure.persistence.influxdb.AlarmStateHistoryInfluxDbRepositoryImpl;
import monasca.api.infrastructure.persistence.influxdb.MeasurementInfluxDbRepositoryImpl;
import monasca.api.infrastructure.persistence.influxdb.MetricDefinitionInfluxDbRepositoryImpl;
import monasca.api.infrastructure.persistence.influxdb.StatisticInfluxDbRepositoryImpl;
import monasca.api.infrastructure.persistence.mysql.AlarmDefinitionMySqlRepositoryImpl;
import monasca.api.infrastructure.persistence.mysql.AlarmMySqlRepositoryImpl;
import monasca.api.infrastructure.persistence.mysql.NotificationMethodMySqlRepositoryImpl;
import monasca.api.infrastructure.persistence.vertica.AlarmStateHistoryVerticaRepositoryImpl;
import monasca.api.infrastructure.persistence.vertica.MeasurementVerticaRepositoryImpl;
import monasca.api.infrastructure.persistence.vertica.MetricDefinitionVerticaRepositoryImpl;
import monasca.api.infrastructure.persistence.vertica.StatisticVerticaRepositoryImpl;
import monasca.api.ApiConfig;
import monasca.api.domain.model.alarm.AlarmRepo;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepo;
import monasca.api.domain.model.measurement.MeasurementRepo;
import monasca.api.domain.model.metric.MetricDefinitionRepo;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepo;
import monasca.api.domain.model.statistic.StatisticRepo;
import monasca.api.infrastructure.persistence.influxdb.InfluxV8AlarmStateHistoryRepo;
import monasca.api.infrastructure.persistence.influxdb.InfluxV8MeasurementRepo;
import monasca.api.infrastructure.persistence.influxdb.InfluxV8MetricDefinitionRepo;
import monasca.api.infrastructure.persistence.influxdb.InfluxV8StatisticRepo;
import monasca.api.infrastructure.persistence.influxdb.InfluxV9AlarmStateHistoryRepo;
import monasca.api.infrastructure.persistence.influxdb.InfluxV9MeasurementRepo;
import monasca.api.infrastructure.persistence.influxdb.InfluxV9MetricDefinitionRepo;
import monasca.api.infrastructure.persistence.influxdb.InfluxV9RepoReader;
import monasca.api.infrastructure.persistence.influxdb.InfluxV9StatisticRepo;
import monasca.api.infrastructure.persistence.mysql.AlarmDefinitionMySqlRepoImpl;
import monasca.api.infrastructure.persistence.mysql.AlarmMySqlRepoImpl;
import monasca.api.infrastructure.persistence.mysql.NotificationMethodMySqlRepoImpl;
import monasca.api.infrastructure.persistence.vertica.AlarmStateHistoryVerticaRepoImpl;
import monasca.api.infrastructure.persistence.vertica.MeasurementVerticaRepoImpl;
import monasca.api.infrastructure.persistence.vertica.MetricDefinitionVerticaRepoImpl;
import monasca.api.infrastructure.persistence.vertica.StatisticVerticaRepoImpl;
/**
* Infrastructure layer bindings.
*/
public class InfrastructureModule extends AbstractModule {
private MonApiConfiguration config;
private ApiConfig config;
public InfrastructureModule(MonApiConfiguration config) {
private static final String VERTICA = "vertica";
private static final String INFLUXDB = "influxdb";
private static final String INFLUXDB_V8 = "v8";
private static final String INFLUXDB_V9 = "v9";
public InfrastructureModule(ApiConfig config) {
this.config = config;
}
@Override
protected void configure() {
// Bind repositories
bind(AlarmRepository.class).to(AlarmMySqlRepositoryImpl.class).in(Singleton.class);
bind(AlarmDefinitionRepository.class).to(AlarmDefinitionMySqlRepositoryImpl.class).in(
bind(AlarmRepo.class).to(AlarmMySqlRepoImpl.class).in(Singleton.class);
bind(AlarmDefinitionRepo.class).to(AlarmDefinitionMySqlRepoImpl.class).in(
Singleton.class);
if (config.databaseConfiguration.getDatabaseType().trim().toLowerCase().equals("vertica")) {
bind(AlarmStateHistoryRepository.class).to(AlarmStateHistoryVerticaRepositoryImpl.class).in(
if (config.databaseConfiguration.getDatabaseType().trim().equalsIgnoreCase(VERTICA)) {
bind(AlarmStateHistoryRepo.class).to(AlarmStateHistoryVerticaRepoImpl.class).in(
Singleton.class);
bind(MetricDefinitionRepository.class).to(MetricDefinitionVerticaRepositoryImpl.class).in(
bind(MetricDefinitionRepo.class).to(MetricDefinitionVerticaRepoImpl.class).in(
Singleton.class);
bind(MeasurementRepository.class).to(MeasurementVerticaRepositoryImpl.class).in(
bind(MeasurementRepo.class).to(MeasurementVerticaRepoImpl.class).in(
Singleton.class);
bind(StatisticRepository.class).to(StatisticVerticaRepositoryImpl.class).in(Singleton.class);
} else if (config.databaseConfiguration.getDatabaseType().trim().toLowerCase()
.equals("influxdb")) {
bind(AlarmStateHistoryRepository.class).to(AlarmStateHistoryInfluxDbRepositoryImpl.class).in(
Singleton.class);
bind(MetricDefinitionRepository.class).to(MetricDefinitionInfluxDbRepositoryImpl.class).in(
Singleton.class);
bind(MeasurementRepository.class).to(MeasurementInfluxDbRepositoryImpl.class).in(
Singleton.class);
bind(StatisticRepository.class).to(StatisticInfluxDbRepositoryImpl.class).in(Singleton.class);
bind(StatisticRepo.class).to(StatisticVerticaRepoImpl.class).in(Singleton.class);
} else if (config.databaseConfiguration.getDatabaseType().trim().equalsIgnoreCase(INFLUXDB)) {
// Check for null to not break existing configs. If no version, default to V8.
if (config.influxDB.getVersion() == null
|| config.influxDB.getVersion().trim().equalsIgnoreCase(INFLUXDB_V8)) {
bind(AlarmStateHistoryRepo.class).to(InfluxV8AlarmStateHistoryRepo.class)
.in(Singleton.class);
bind(MetricDefinitionRepo.class).to(InfluxV8MetricDefinitionRepo.class).in(Singleton.class);
bind(MeasurementRepo.class).to(InfluxV8MeasurementRepo.class).in(Singleton.class);
bind(StatisticRepo.class).to(InfluxV8StatisticRepo.class).in(Singleton.class);
} else if (config.influxDB.getVersion().trim().equalsIgnoreCase(INFLUXDB_V9)) {
bind(InfluxV9RepoReader.class).in(Singleton.class);
bind(AlarmStateHistoryRepo.class).to(InfluxV9AlarmStateHistoryRepo.class)
.in(Singleton.class);
bind(MetricDefinitionRepo.class).to(InfluxV9MetricDefinitionRepo.class).in(Singleton.class);
bind(MeasurementRepo.class).to(InfluxV9MeasurementRepo.class).in(Singleton.class);
bind(StatisticRepo.class).to(InfluxV9StatisticRepo.class).in(Singleton.class);
} else {
throw new ProvisionException(
"Found unknown Influxdb version: " + config.influxDB.getVersion() + "."
+ " Supported Influxdb versions are 'v8' and 'v9'. Please check your config file");
}
} else {
throw new ProvisionException("Failed to detect supported database. Supported databases are "
+ "'vertica' and 'influxdb'. Check your config file.");
}
bind(NotificationMethodRepository.class).to(NotificationMethodMySqlRepositoryImpl.class).in(
bind(NotificationMethodRepo.class).to(NotificationMethodMySqlRepoImpl.class).in(
Singleton.class);
}

View File

@ -13,7 +13,6 @@
*/
package monasca.api.infrastructure.persistence.influxdb;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@ -39,26 +38,27 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.google.inject.Inject;
import monasca.api.MonApiConfiguration;
import monasca.api.domain.model.common.Paged;
import monasca.api.ApiConfig;
import monasca.common.model.alarm.AlarmState;
import monasca.common.model.metric.MetricDefinition;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistory;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepository;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepo;
import monasca.api.infrastructure.persistence.DimensionQueries;
public class AlarmStateHistoryInfluxDbRepositoryImpl implements AlarmStateHistoryRepository {
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.buildAlarmsPart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.findAlarmIds;
public class InfluxV8AlarmStateHistoryRepo implements AlarmStateHistoryRepo {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private static final TypeReference<List<MetricDefinition>> METRICS_TYPE =
new TypeReference<List<MetricDefinition>>() {};
private static final Logger logger = LoggerFactory
.getLogger(AlarmStateHistoryInfluxDbRepositoryImpl.class);
private static final String FIND_ALARMS_SQL =
"select distinct a.id from alarm as a " +
"join alarm_definition as ad on a.alarm_definition_id=ad.id " +
"%s " +
"where ad.tenant_id = :tenantId and ad.deleted_at is NULL order by ad.created_at";
private final MonApiConfiguration config;
.getLogger(InfluxV8AlarmStateHistoryRepo.class);
private final ApiConfig config;
private final InfluxDB influxDB;
private final DBI mysql;
@ -68,8 +68,8 @@ public class AlarmStateHistoryInfluxDbRepositoryImpl implements AlarmStateHistor
}
@Inject
public AlarmStateHistoryInfluxDbRepositoryImpl(@Named("mysql") DBI mysql,
MonApiConfiguration config, InfluxDB influxDB) {
public InfluxV8AlarmStateHistoryRepo(@Named("mysql") DBI mysql, ApiConfig config,
InfluxDB influxDB) {
this.mysql = mysql;
this.config = config;
this.influxDB = influxDB;
@ -83,37 +83,27 @@ public class AlarmStateHistoryInfluxDbRepositoryImpl implements AlarmStateHistor
}
String buildQueryForFindById(String tenantId, String alarmId, String offset) throws Exception {
String offsetPart = Utils.buildOffsetPart(offset);
String offsetPart = InfluxV8Utils.buildOffsetPart(offset);
return String.format("select alarm_id, metrics, old_state, new_state, reason, reason_data "
+ "from alarm_state_history where tenant_id = '%1$s' and alarm_id = '%2$s' %3$s",
Utils.SQLSanitizer.sanitize(tenantId), Utils.SQLSanitizer.sanitize(alarmId), offsetPart);
InfluxV8Utils.SQLSanitizer.sanitize(tenantId), InfluxV8Utils.SQLSanitizer.sanitize(alarmId), offsetPart);
}
@Override
public List<AlarmStateHistory> find(String tenantId, Map<String, String> dimensions,
DateTime startTime, @Nullable DateTime endTime, String offset) throws Exception {
List<String> alarmIds = null;
// Find alarm Ids for dimensions
try (Handle h = mysql.open()) {
final String sql =
String.format(FIND_ALARMS_SQL, buildJoinClauseFor(dimensions));
List<String> alarmIdList = findAlarmIds(this.mysql, tenantId, dimensions);
Query<Map<String, Object>> query = h.createQuery(sql).bind("tenantId", tenantId);
logger.debug("AlarmStateHistory query '{}'", sql);
DimensionQueries.bindDimensionsToQuery(query, dimensions);
alarmIds = query.map(StringMapper.FIRST).list();
}
if (alarmIds == null || alarmIds.isEmpty()) {
if (alarmIdList == null || alarmIdList.isEmpty()) {
logger.debug("AlarmStateHistory no alarmIds");
return Collections.emptyList();
}
logger.debug("AlarmStateHistory alarmIds {}", alarmIds);
logger.debug("AlarmStateHistory alarmIds {}", alarmIdList);
String timePart = buildTimePart(startTime, endTime);
String alarmsPart = buildAlarmsPart(alarmIds);
String offsetPart = Utils.buildOffsetPart(offset);
String alarmsPart = buildAlarmsPart(alarmIdList);
String offsetPart = InfluxV8Utils.buildOffsetPart(offset);
String query = buildQueryForFind(tenantId, timePart, alarmsPart, offsetPart);
logger.debug("AlarmStateHistory query for influxdb '{}'", query);
@ -122,51 +112,16 @@ public class AlarmStateHistoryInfluxDbRepositoryImpl implements AlarmStateHistor
}
private String buildJoinClauseFor(Map<String, String> dimensions) {
if ((dimensions == null) || dimensions.isEmpty()) {
return "";
}
final StringBuilder sbJoin = new StringBuilder("join alarm_metric as am on a.id=am.alarm_id ");
sbJoin
.append("join metric_definition_dimensions as mdd on am.metric_definition_dimensions_id=mdd.id ");
for (int i = 0; i < dimensions.size(); i++) {
final String tableAlias = "md" + i;
sbJoin.append(" inner join metric_dimension ").append(tableAlias).append(" on ")
.append(tableAlias).append(".name = :dname").append(i).append(" and ")
.append(tableAlias).append(".value = :dvalue").append(i)
.append(" and mdd.metric_dimension_set_id = ")
.append(tableAlias).append(".dimension_set_id");
}
return sbJoin.toString();
}
String buildTimePart(DateTime startTime, DateTime endTime) {
return Utils.WhereClauseBuilder.buildTimePart(startTime, endTime);
return InfluxV8Utils.WhereClauseBuilder.buildTimePart(startTime, endTime);
}
String buildQueryForFind(String tenantId, String timePart, String alarmsPart, String offsetPart) throws Exception {
return String.format("select alarm_id, metrics, old_state, new_state, reason, reason_data "
+ "from alarm_state_history where tenant_id = '%1$s' %2$s %3$s %4$s",
Utils.SQLSanitizer.sanitize(tenantId), timePart, alarmsPart, offsetPart);
InfluxV8Utils.SQLSanitizer.sanitize(tenantId), timePart, alarmsPart, offsetPart);
}
String buildAlarmsPart(List<String> alarmIds) {
StringBuilder sb = new StringBuilder();
for (String alarmId : alarmIds) {
if (sb.length() > 0) {
sb.append(" or ");
}
sb.append(String.format(" alarm_id = '%1$s' ", alarmId));
}
if (sb.length() > 0) {
sb.insert(0, " and (");
sb.insert(sb.length(), ")");
}
return sb.toString();
}
@SuppressWarnings("unchecked")
private List<AlarmStateHistory> queryInfluxDBForAlarmStateHistory(String query) {
@ -176,7 +131,7 @@ public class AlarmStateHistoryInfluxDbRepositoryImpl implements AlarmStateHistor
try {
result = this.influxDB.Query(this.config.influxDB.getName(), query, TimeUnit.MILLISECONDS);
} catch (Exception e) {
if (e.getMessage().startsWith(Utils.COULD_NOT_LOOK_UP_COLUMNS_EXC_MSG)) {
if (e.getMessage().startsWith(InfluxV8Utils.COULD_NOT_LOOK_UP_COLUMNS_EXC_MSG)) {
return new LinkedList<>();
} else {
logger.error("Failed to get data from InfluxDB", e);

View File

@ -15,8 +15,8 @@ package monasca.api.infrastructure.persistence.influxdb;
import com.google.inject.Inject;
import monasca.api.MonApiConfiguration;
import monasca.api.domain.model.measurement.MeasurementRepository;
import monasca.api.ApiConfig;
import monasca.api.domain.model.measurement.MeasurementRepo;
import monasca.api.domain.model.measurement.Measurements;
import org.influxdb.InfluxDB;
@ -27,7 +27,6 @@ import org.joda.time.format.ISODateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -35,21 +34,21 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import static monasca.api.infrastructure.persistence.influxdb.Utils.buildSerieNameRegex;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.buildSerieNameRegex;
public class MeasurementInfluxDbRepositoryImpl implements MeasurementRepository {
public class InfluxV8MeasurementRepo implements MeasurementRepo {
private static final Logger logger = LoggerFactory
.getLogger(MeasurementInfluxDbRepositoryImpl.class);
.getLogger(InfluxV8MeasurementRepo.class);
private final MonApiConfiguration config;
private final ApiConfig config;
private final InfluxDB influxDB;
public static final DateTimeFormatter DATETIME_FORMATTER = ISODateTimeFormat.dateTimeNoMillis()
.withZoneUTC();
@Inject
public MeasurementInfluxDbRepositoryImpl(MonApiConfiguration config, InfluxDB influxDB) {
public InfluxV8MeasurementRepo(ApiConfig config, InfluxDB influxDB) {
this.config = config;
this.influxDB = influxDB;
@ -63,9 +62,9 @@ public class MeasurementInfluxDbRepositoryImpl implements MeasurementRepository
String serieNameRegex = buildSerieNameRegex(tenantId, config.region, name, dimensions);
String timePart = Utils.WhereClauseBuilder.buildTimePart(startTime, endTime);
String timePart = InfluxV8Utils.WhereClauseBuilder.buildTimePart(startTime, endTime);
String offsetPart = Utils.buildOffsetPart(offset);
String offsetPart = InfluxV8Utils.buildOffsetPart(offset);
String query =
String.format("select value " + "from /%1$s/ where 1 = 1 " + " %2$s %3$s",
@ -76,7 +75,7 @@ public class MeasurementInfluxDbRepositoryImpl implements MeasurementRepository
try {
result = this.influxDB.Query(this.config.influxDB.getName(), query, TimeUnit.MILLISECONDS);
} catch (RuntimeException e) {
if (e.getMessage().startsWith(Utils.COULD_NOT_LOOK_UP_COLUMNS_EXC_MSG)) {
if (e.getMessage().startsWith(InfluxV8Utils.COULD_NOT_LOOK_UP_COLUMNS_EXC_MSG)) {
return new LinkedList<>();
} else {
logger.error("Failed to get data from InfluxDB", e);
@ -92,10 +91,10 @@ public class MeasurementInfluxDbRepositoryImpl implements MeasurementRepository
for (Serie serie : result) {
Utils.SerieNameDecoder serieNameDecoder;
InfluxV8Utils.SerieNameDecoder serieNameDecoder;
try {
serieNameDecoder = new Utils.SerieNameDecoder(serie.getName());
} catch (Utils.SerieNameDecodeException e) {
serieNameDecoder = new InfluxV8Utils.SerieNameDecoder(serie.getName());
} catch (InfluxV8Utils.SerieNameDecodeException e) {
logger.warn("Dropping series name that is not decodable: {}", serie.getName(), e);
continue;
}

View File

@ -25,26 +25,26 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import monasca.api.MonApiConfiguration;
import monasca.api.ApiConfig;
import monasca.api.domain.model.common.Paged;
import monasca.api.domain.model.metric.MetricDefinitionRepository;
import monasca.api.domain.model.metric.MetricDefinitionRepo;
import monasca.common.model.metric.MetricDefinition;
import static monasca.api.infrastructure.persistence.influxdb.Utils.buildSerieNameRegex;
import static monasca.api.infrastructure.persistence.influxdb.Utils.urlDecodeUTF8;
import static monasca.api.infrastructure.persistence.influxdb.Utils.urlEncodeUTF8;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.buildSerieNameRegex;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.urlDecodeUTF8;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.urlEncodeUTF8;
public class MetricDefinitionInfluxDbRepositoryImpl implements MetricDefinitionRepository {
public class InfluxV8MetricDefinitionRepo implements MetricDefinitionRepo {
private static final Logger
logger =
LoggerFactory.getLogger(MetricDefinitionInfluxDbRepositoryImpl.class);
LoggerFactory.getLogger(InfluxV8MetricDefinitionRepo.class);
private final MonApiConfiguration config;
private final ApiConfig config;
private final InfluxDB influxDB;
@Inject
public MetricDefinitionInfluxDbRepositoryImpl(MonApiConfiguration config, InfluxDB influxDB) {
public InfluxV8MetricDefinitionRepo(ApiConfig config, InfluxDB influxDB) {
this.config = config;
this.influxDB = influxDB;
}
@ -86,11 +86,11 @@ public class MetricDefinitionInfluxDbRepositoryImpl implements MetricDefinitionR
}
}
Utils.SerieNameDecoder serieNameDecoder;
InfluxV8Utils.SerieNameDecoder serieNameDecoder;
try {
serieNameDecoder = new Utils.SerieNameDecoder(encodedMetricName);
} catch (Utils.SerieNameDecodeException e) {
serieNameDecoder = new InfluxV8Utils.SerieNameDecoder(encodedMetricName);
} catch (InfluxV8Utils.SerieNameDecodeException e) {
logger.warn("Dropping series name that is not decodable: {}", point.get("name"), e);
continue;
}

View File

@ -15,8 +15,8 @@ package monasca.api.infrastructure.persistence.influxdb;
import com.google.inject.Inject;
import monasca.api.MonApiConfiguration;
import monasca.api.domain.model.statistic.StatisticRepository;
import monasca.api.ApiConfig;
import monasca.api.domain.model.statistic.StatisticRepo;
import monasca.api.domain.model.statistic.Statistics;
import org.influxdb.InfluxDB;
@ -35,21 +35,21 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import static monasca.api.infrastructure.persistence.influxdb.Utils.buildSerieNameRegex;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.buildSerieNameRegex;
public class StatisticInfluxDbRepositoryImpl implements StatisticRepository {
public class InfluxV8StatisticRepo implements StatisticRepo {
private static final Logger logger = LoggerFactory
.getLogger(StatisticInfluxDbRepositoryImpl.class);
.getLogger(InfluxV8StatisticRepo.class);
private final MonApiConfiguration config;
private final ApiConfig config;
private final InfluxDB influxDB;
public static final DateTimeFormatter DATETIME_FORMATTER = ISODateTimeFormat.dateTimeNoMillis()
.withZoneUTC();
@Inject
public StatisticInfluxDbRepositoryImpl(MonApiConfiguration config, InfluxDB influxDB) {
public InfluxV8StatisticRepo(ApiConfig config, InfluxDB influxDB) {
this.config = config;
this.influxDB = influxDB;
}
@ -62,7 +62,7 @@ public class StatisticInfluxDbRepositoryImpl implements StatisticRepository {
String serieNameRegex = buildSerieNameRegex(tenantId, config.region, name, dimensions);
String statsPart = buildStatsPart(statistics);
String timePart = Utils.WhereClauseBuilder.buildTimePart(startTime, endTime);
String timePart = InfluxV8Utils.WhereClauseBuilder.buildTimePart(startTime, endTime);
String periodPart = buildPeriodPart(period);
String query =
@ -74,7 +74,7 @@ public class StatisticInfluxDbRepositoryImpl implements StatisticRepository {
try {
result = this.influxDB.Query(this.config.influxDB.getName(), query, TimeUnit.MILLISECONDS);
} catch (RuntimeException e) {
if (e.getMessage().startsWith(Utils.COULD_NOT_LOOK_UP_COLUMNS_EXC_MSG)) {
if (e.getMessage().startsWith(InfluxV8Utils.COULD_NOT_LOOK_UP_COLUMNS_EXC_MSG)) {
return new LinkedList<>();
} else {
logger.error("Failed to get data from InfluxDB", e);
@ -90,10 +90,10 @@ public class StatisticInfluxDbRepositoryImpl implements StatisticRepository {
List<Statistics> statisticsList = new LinkedList<Statistics>();
for (Serie serie : result) {
Utils.SerieNameDecoder serieNameDecoder;
InfluxV8Utils.SerieNameDecoder serieNameDecoder;
try {
serieNameDecoder = new Utils.SerieNameDecoder(serie.getName());
} catch (Utils.SerieNameDecodeException e) {
serieNameDecoder = new InfluxV8Utils.SerieNameDecoder(serie.getName());
} catch (InfluxV8Utils.SerieNameDecodeException e) {
logger.warn("Dropping series name that is not decodable: {}", serie.getName(), e);
continue;
}

View File

@ -14,25 +14,36 @@
package monasca.api.infrastructure.persistence.influxdb;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.Query;
import org.skife.jdbi.v2.util.StringMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import monasca.api.domain.model.common.Paged;
import monasca.api.infrastructure.persistence.DimensionQueries;
final class Utils {
final class InfluxV8Utils {
private static final Logger logger = LoggerFactory
.getLogger(InfluxV8Utils.class);
// Serie names match this pattern.
private static final Pattern serieNamePattern = Pattern.compile("^.+\\?.+&.+(&.+=.+)*$");
static final String COULD_NOT_LOOK_UP_COLUMNS_EXC_MSG = "Couldn't look up columns";
private Utils() {
private InfluxV8Utils() {
}
/**
@ -43,13 +54,13 @@ final class Utils {
private SQLSanitizer() {
}
private static final Pattern sqlUnsafePattern = Pattern.compile("^.*('|;)+.*$");
private static final Pattern sqlUnsafePattern = Pattern.compile("^.*('|;|\")+.*$");
static String sanitize(final String taintedString) throws Exception {
Matcher m = sqlUnsafePattern.matcher(taintedString);
if (m.matches()) {
throw new Exception(String.format("Input from user contains single quote ['] or " +
"semi-colon [;] characters[ %1$s ]", taintedString));
"semi-colon [;] or double quote [\"] characters[ %1$s ]", taintedString));
}
return taintedString;
@ -253,5 +264,69 @@ final class Utils {
}
}
public static List<String> findAlarmIds(DBI mysql, String tenantId,
Map<String, String> dimensions) {
final String FIND_ALARMS_SQL = "select distinct a.id from alarm as a " +
"join alarm_definition as ad on a.alarm_definition_id=ad.id " +
"%s " +
"where ad.tenant_id = :tenantId and ad.deleted_at is NULL order by ad.created_at";
List<String> alarmIdList = null;
try (Handle h = mysql.open()) {
final String sql = String.format(FIND_ALARMS_SQL, buildJoinClauseFor(dimensions));
Query<Map<String, Object>> query = h.createQuery(sql).bind("tenantId", tenantId);
logger.debug("AlarmStateHistory query '{}'", sql);
DimensionQueries.bindDimensionsToQuery(query, dimensions);
alarmIdList = query.map(StringMapper.FIRST).list();
}
return alarmIdList;
}
private static String buildJoinClauseFor(Map<String, String> dimensions) {
if ((dimensions == null) || dimensions.isEmpty()) {
return "";
}
final StringBuilder sbJoin = new StringBuilder("join alarm_metric as am on a.id=am.alarm_id ");
sbJoin.append(
"join metric_definition_dimensions as mdd on am.metric_definition_dimensions_id=mdd.id ");
for (int i = 0; i < dimensions.size(); i++) {
final String tableAlias = "md" + i;
sbJoin.append(" inner join metric_dimension ").append(tableAlias).append(" on ")
.append(tableAlias).append(".name = :dname").append(i).append(" and ").append(tableAlias)
.append(".value = :dvalue").append(i).append(" and mdd.metric_dimension_set_id = ")
.append(tableAlias).append(".dimension_set_id");
}
return sbJoin.toString();
}
public static String buildAlarmsPart(List<String> alarmIds) {
StringBuilder sb = new StringBuilder();
for (String alarmId : alarmIds) {
if (sb.length() > 0) {
sb.append(" or ");
}
sb.append(String.format(" alarm_id = '%1$s' ", alarmId));
}
if (sb.length() > 0) {
sb.insert(0, " and (");
sb.insert(sb.length(), ")");
}
return sb.toString();
}
}

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
*
* 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 monasca.api.infrastructure.persistence.influxdb;
import com.google.inject.Inject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.skife.jdbi.v2.DBI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import javax.inject.Named;
import monasca.api.ApiConfig;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistory;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepo;
import monasca.common.model.alarm.AlarmState;
import monasca.common.model.metric.MetricDefinition;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.WhereClauseBuilder.buildTimePart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.buildAlarmsPart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.findAlarmIds;
public class InfluxV9AlarmStateHistoryRepo implements AlarmStateHistoryRepo {
private static final Logger logger = LoggerFactory
.getLogger(InfluxV9AlarmStateHistoryRepo.class);
private final DBI mysql;
private final ApiConfig config;
private final String region;
private final InfluxV9RepoReader influxV9RepoReader;
private final ObjectMapper objectMapper = new ObjectMapper();
private final SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz");
private static final TypeReference<List<MetricDefinition>> METRICS_TYPE =
new TypeReference<List<MetricDefinition>>() {};
@Inject
public InfluxV9AlarmStateHistoryRepo(@Named("mysql") DBI mysql,
ApiConfig config,
InfluxV9RepoReader influxV9RepoReader) {
this.mysql = mysql;
this.config = config;
this.region = config.region;
this.influxV9RepoReader = influxV9RepoReader;
}
@Override
public List<AlarmStateHistory> findById(String tenantId, String alarmId, String offset)
throws Exception {
String q = String.format("select alarm_id, metrics, old_state, new_state, reason, reason_data "
+ "from alarm_state_history where tenant_id = '%1$s' and alarm_id = '%2$s'",
InfluxV8Utils.SQLSanitizer.sanitize(tenantId),
InfluxV8Utils.SQLSanitizer.sanitize(alarmId));
logger.debug("Alarm state history query: {}", q);
String r = this.influxV9RepoReader.read(q);
Series series = this.objectMapper.readValue(r, Series.class);
List<AlarmStateHistory> alarmStateHistoryList = alarmStateHistoryList(series);
logger.debug("Found {} alarm state transitions matching query", alarmStateHistoryList.size());
return alarmStateHistoryList;
}
@Override
public List<AlarmStateHistory> find(String tenantId, Map<String, String> dimensions,
DateTime startTime, @Nullable DateTime endTime,
@Nullable String offset) throws Exception {
List<String> alarmIdList = findAlarmIds(this.mysql, tenantId, dimensions);
if (alarmIdList == null || alarmIdList.isEmpty()) {
return new ArrayList<>();
}
String timePart = buildTimePart(startTime, endTime);
String alarmsPart = buildAlarmsPart(alarmIdList);
String q = String.format("select alarm_id, metrics, old_state, new_state, reason, reason_data "
+ "from alarm_state_history where tenant_id = '%1$s' %2$s %3$s",
InfluxV8Utils.SQLSanitizer.sanitize(tenantId), timePart, alarmsPart);
String r = this.influxV9RepoReader.read(q);
Series series = this.objectMapper.readValue(r, Series.class);
List<AlarmStateHistory> alarmStateHistoryList = alarmStateHistoryList(series);
logger.debug("Found {} alarm state transitions matching query", alarmStateHistoryList.size());
return alarmStateHistoryList;
}
private List<AlarmStateHistory> alarmStateHistoryList(Series series) {
List<AlarmStateHistory> alarmStateHistoryList = new LinkedList<>();
if (!series.isEmpty()) {
for (Row row : series.getRows()) {
for (String[] values : row.getValues()) {
AlarmStateHistory alarmStateHistory = new AlarmStateHistory();
Date date;
try {
date = this.simpleDateFormat.parse(values[0] + " UTC");
} catch (ParseException e) {
logger.error("Failed to parse time", e);
continue;
}
DateTime dateTime = new DateTime(date.getTime(), DateTimeZone.UTC);
alarmStateHistory.setTimestamp(dateTime);
alarmStateHistory.setAlarmId(values[1]);
List<MetricDefinition> metricDefinitionList;
try {
metricDefinitionList = this.objectMapper.readValue(values[2], METRICS_TYPE);
} catch (IOException e) {
logger.error("Failed to parse metrics", e);
continue;
}
alarmStateHistory.setMetrics(metricDefinitionList);
alarmStateHistory.setOldState(AlarmState.valueOf(values[3]));
alarmStateHistory.setNewState(AlarmState.valueOf(values[4]));
alarmStateHistory.setReason(values[5]);
alarmStateHistory.setReasonData(values[6]);
alarmStateHistoryList.add(alarmStateHistory);
}
}
}
return alarmStateHistoryList;
}
}

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
*
* 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 monasca.api.infrastructure.persistence.influxdb;
import com.google.inject.Inject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import monasca.api.ApiConfig;
import monasca.api.domain.model.measurement.MeasurementRepo;
import monasca.api.domain.model.measurement.Measurements;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.dimPart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.endTimePart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.namePart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.regionPart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.startTimePart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.tenantIdPart;
public class InfluxV9MeasurementRepo implements MeasurementRepo {
private static final Logger logger = LoggerFactory
.getLogger(InfluxV9MeasurementRepo.class);
private final ApiConfig config;
private final String region;
private final InfluxV9RepoReader influxV9RepoReader;
private final ObjectMapper objectMapper = new ObjectMapper();
@Inject
public InfluxV9MeasurementRepo(ApiConfig config,
InfluxV9RepoReader influxV9RepoReader) {
this.config = config;
this.region = config.region;
this.influxV9RepoReader = influxV9RepoReader;
}
@Override
public List<Measurements> find(String tenantId, String name, Map<String, String> dimensions,
DateTime startTime, @Nullable DateTime endTime,
@Nullable String offset) throws Exception {
String q = String.format("select value %1$s where %2$s %3$s %4$s %5$s %6$s", namePart(name),
tenantIdPart(tenantId), regionPart(this.region), startTimePart(startTime),
dimPart(dimensions), endTimePart(endTime));
logger.debug("Measurements query: {}", q);
String r = this.influxV9RepoReader.read(q);
Series series = this.objectMapper.readValue(r, Series.class);
List<Measurements> measurementsList = measurementsList(series);
logger.debug("Found {} metrics matching query", measurementsList.size());
return measurementsList;
}
private List<Measurements> measurementsList(Series series) {
List<Measurements> measurementsList = new LinkedList<>();
if (!series.isEmpty()) {
for (Row row : series.getRows()) {
// Influxdb 0.9.0 does not return dimensions at this time.
Measurements measurements = new Measurements(row.getName(), new HashMap());
for (String[] values : row.getValues()) {
measurements.addMeasurement(new Object[]{values[0], Double.parseDouble(values[1])});
}
measurementsList.add(measurements);
}
}
return measurementsList;
}
}

View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
*
* 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 monasca.api.infrastructure.persistence.influxdb;
import com.google.inject.Inject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import monasca.api.ApiConfig;
import monasca.api.domain.model.metric.MetricDefinitionRepo;
import monasca.common.model.metric.MetricDefinition;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.dimPart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.namePart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.regionPart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.tenantIdPart;
public class InfluxV9MetricDefinitionRepo implements MetricDefinitionRepo {
private static final Logger logger = LoggerFactory.getLogger(InfluxV9MetricDefinitionRepo.class);
private final ApiConfig config;
private final InfluxV9RepoReader influxV9RepoReader;
private final String region;
private final ObjectMapper objectMapper = new ObjectMapper();
@Inject
public InfluxV9MetricDefinitionRepo(ApiConfig config,
InfluxV9RepoReader influxV9RepoReader) {
this.config = config;
this.region = config.region;
this.influxV9RepoReader = influxV9RepoReader;
}
@Override
public List<MetricDefinition> find(String tenantId, String name,
Map<String, String> dimensions,
String offset) throws Exception {
String
q =
String.format("show series %1$s where %2$s %3$s %4$s", namePart(name), tenantIdPart(
tenantId),
regionPart(this.region), dimPart(dimensions));
logger.debug("Metric definition query: {}", q);
String r = this.influxV9RepoReader.read(q);
Series series = this.objectMapper.readValue(r, Series.class);
List<MetricDefinition> metricDefinitionList = metricDefinitionList(series);
logger.debug("Found {} metric definitions matching query", metricDefinitionList.size());
return metricDefinitionList;
}
private List<MetricDefinition> metricDefinitionList(Series series) {
List<MetricDefinition> metricDefinitionList = new ArrayList<>();
if (!series.isEmpty()) {
for (Row row : series.getRows()) {
for (String[] values : row.getValues()) {
metricDefinitionList.add(new MetricDefinition(row.getName(), dims(values, row.getColumns())));
}
}
}
return metricDefinitionList;
}
private Map<String, String> dims(String[] vals, String[] cols) {
Map<String, String> dims = new HashMap<>();
for (int i = 0; i < cols.length; ++i) {
if (!vals[i].equalsIgnoreCase("null")) {
dims.put(cols[i], vals[i]);
}
}
return dims;
}
}

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
*
* 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 monasca.api.infrastructure.persistence.influxdb;
import com.google.inject.Inject;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URLEncoder;
import monasca.api.ApiConfig;
public class InfluxV9RepoReader {
private static final Logger logger = LoggerFactory.getLogger(InfluxV9RepoReader.class);
private final ApiConfig config;
private final String influxName;
private final String influxUrl;
private final String influxCreds;
private final String influxUser;
private final String influxPass;
private final String baseAuthHeader;
private final CloseableHttpClient httpClient;
@Inject
public InfluxV9RepoReader(final ApiConfig config) {
this.config = config;
this.influxName = config.influxDB.getName();
this.influxUrl = config.influxDB.getUrl() + "/query";
this.influxUser = config.influxDB.getUser();
this.influxPass = config.influxDB.getPassword();
this.influxCreds = this.influxUser + ":" + this.influxPass;
this.baseAuthHeader = "Basic " + new String(Base64.encodeBase64(this.influxCreds.getBytes()));
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(config.influxDB.getMaxHttpConnections());
// We inject InfluxV9RepoReader as a singleton. So, we must share connections safely.
this.httpClient = HttpClients.custom().setConnectionManager(cm).build();
}
protected String read(final String query) throws Exception {
HttpGet request = new HttpGet(this.influxUrl + "?q=" + URLEncoder.encode(query, "UTF-8")
+ "&db=" + URLEncoder.encode(this.influxName, "UTF-8"));
request.addHeader("content-type", "application/json");
request.addHeader("Authorization", this.baseAuthHeader);
try {
logger.debug("Sending query {} to influx database {} at {}", query, this.influxName,
this.influxUrl);
HttpResponse response = this.httpClient.execute(request);
int rc = response.getStatusLine().getStatusCode();
if (rc != HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity, "UTF-8");
logger.error("Failed to query influx database {} at {}: {}",
this.influxName, this.influxUrl, String.valueOf(rc));
logger.error("Http response: {}", responseString);
throw new Exception(rc + ":" + responseString);
}
logger.debug("Successfully queried influx database {} at {}",
this.influxName, this.influxUrl);
HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
} finally {
request.releaseConnection();
}
}
}

View File

@ -0,0 +1,132 @@
/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
*
* 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 monasca.api.infrastructure.persistence.influxdb;
import com.google.inject.Inject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import monasca.api.ApiConfig;
import monasca.api.domain.model.statistic.StatisticRepo;
import monasca.api.domain.model.statistic.Statistics;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.dimPart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.endTimePart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.namePart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.regionPart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.startTimePart;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV9Utils.tenantIdPart;
public class InfluxV9StatisticRepo implements StatisticRepo{
private static final Logger logger = LoggerFactory.getLogger(InfluxV9StatisticRepo.class);
private final ApiConfig config;
private final String region;
private final InfluxV9RepoReader influxV9RepoReader;
private final ObjectMapper objectMapper = new ObjectMapper();
@Inject
public InfluxV9StatisticRepo(ApiConfig config,
InfluxV9RepoReader influxV9RepoReader) {
this.config = config;
this.region = config.region;
this.influxV9RepoReader = influxV9RepoReader;
}
@Override
public List<Statistics> find(String tenantId, String name, Map<String, String> dimensions,
DateTime startTime, @Nullable DateTime endTime,
List<String> statistics, int period) throws Exception {
String q = String.format("select %1$s %2$s where %3$s %4$s %5$s %6$s %7$s %8$s",
funcPart(statistics), namePart(name),
tenantIdPart(tenantId), regionPart(this.region),
startTimePart(startTime), dimPart(dimensions),
endTimePart(endTime), periodPart(period));
logger.debug("Measurements query: {}", q);
String r = this.influxV9RepoReader.read(q);
Series series = this.objectMapper.readValue(r, Series.class);
List<Statistics> statisticsList = statisticslist(series);
logger.debug("Found {} metric definitions matching query", statisticsList.size());
return statisticsList;
}
private List<Statistics> statisticslist(Series series) {
List<Statistics> statisticsList = new LinkedList<>();
if (!series.isEmpty()) {
for (Row row : series.getRows()) {
Statistics statistics = new Statistics(row.getName(), new HashMap<String, String>(),
Arrays.asList(row.getColumns()));
for (Object[] values : row.getValues()) {
statistics.addStatistics(Arrays.asList(values));
}
statisticsList.add(statistics);
}
}
return statisticsList;
}
private String funcPart(List<String> statistics) {
StringBuilder sb = new StringBuilder();
for (String stat : statistics) {
if (sb.length() != 0) {
sb.append(",");
}
sb.append(String.format("%1$s(value)", stat));
}
return sb.toString();
}
private String periodPart(int period) {
return period >= 1 ? String.format("group by time(%1$ds)", period) : "";
}
}

View File

@ -0,0 +1,69 @@
package monasca.api.infrastructure.persistence.influxdb;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
import java.util.Map;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.SQLSanitizer.sanitize;
public class InfluxV9Utils {
public static String namePart(String name) throws Exception {
sanitize(name);
if (name != null && !name.isEmpty()) {
return String.format("from \"%1$s\"", name);
} else {
return "";
}
}
public static String tenantIdPart(String tenantId) throws Exception {
if (tenantId == null || tenantId.isEmpty()) {
throw new Exception(String.format("Found invalid tenant id: %1$s", tenantId));
}
sanitize(tenantId);
return "tenant_id=" + "'" + tenantId + "'";
}
public static String regionPart(String region) throws Exception {
sanitize(region);
String s = "";
s += " and region=" + "'" + region + "'";
return s;
}
public static String dimPart(Map<String, String> dims) throws Exception {
StringBuilder sb = new StringBuilder();
if (dims != null && !dims.isEmpty()) {
for (String k : dims.keySet()) {
String v = dims.get(k);
sanitize(k);
sanitize(v);
sb.append(" and " + k + "=" + "'" + v + "'");
}
}
return sb.toString();
}
public static String startTimePart (DateTime startTime) {
return startTime != null ? " and time > " + "'" + ISODateTimeFormat.dateTime().print(startTime) + "'" : "";
}
public static String endTimePart (DateTime endTime) {
return endTime != null ? " and time < " + "'" + ISODateTimeFormat.dateTime().print(endTime) + "'" : "";
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
*
* 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 monasca.api.infrastructure.persistence.influxdb;
public class Series {
public RowsElement[] results;
boolean isEmpty() {
return this.results[0].rows == null;
}
Row[] getRows() {
return this.results[0].rows;
}
}
class RowsElement {
public Row[] rows;
}
class Row {
public String name;
public String[] columns;
public String[][] values;
public String getName() {
return name;
}
public String[] getColumns() {
return columns;
}
public String[][] getValues() {
return values;
}
}

View File

@ -42,7 +42,7 @@ import monasca.common.model.alarm.AlarmSubExpression;
import monasca.common.model.metric.MetricDefinition;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
import monasca.api.infrastructure.persistence.DimensionQueries;
import monasca.api.infrastructure.persistence.SubAlarmDefinitionQueries;
@ -51,7 +51,7 @@ import com.google.common.collect.Lists;
/**
* Alarm repository implementation.
*/
public class AlarmDefinitionMySqlRepositoryImpl implements AlarmDefinitionRepository {
public class AlarmDefinitionMySqlRepoImpl implements AlarmDefinitionRepo {
private static final Joiner COMMA_JOINER = Joiner.on(',');
private static final String SUB_ALARM_SQL =
"select sa.*, sad.dimensions from sub_alarm_definition as sa "
@ -61,7 +61,7 @@ public class AlarmDefinitionMySqlRepositoryImpl implements AlarmDefinitionReposi
private final DBI db;
@Inject
public AlarmDefinitionMySqlRepositoryImpl(@Named("mysql") DBI db) {
public AlarmDefinitionMySqlRepoImpl(@Named("mysql") DBI db) {
this.db = db;
}

View File

@ -15,7 +15,7 @@ package monasca.api.infrastructure.persistence.mysql;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.alarm.Alarm;
import monasca.api.domain.model.alarm.AlarmRepository;
import monasca.api.domain.model.alarm.AlarmRepo;
import monasca.api.domain.model.common.Paged;
import monasca.api.infrastructure.persistence.DimensionQueries;
import monasca.common.model.alarm.AlarmState;
@ -41,8 +41,8 @@ import javax.inject.Named;
/**
* Alarmed metric repository implementation.
*/
public class AlarmMySqlRepositoryImpl implements AlarmRepository {
private static final Logger logger = LoggerFactory.getLogger(AlarmMySqlRepositoryImpl.class);
public class AlarmMySqlRepoImpl implements AlarmRepo {
private static final Logger logger = LoggerFactory.getLogger(AlarmMySqlRepoImpl.class);
private final DBI db;
private static final String ALARM_SQL =
@ -58,7 +58,7 @@ public class AlarmMySqlRepositoryImpl implements AlarmRepository {
+ "where ad.tenant_id = :tenantId and ad.deleted_at is null %s order by a.id %s";
@Inject
public AlarmMySqlRepositoryImpl(@Named("mysql") DBI db) {
public AlarmMySqlRepoImpl(@Named("mysql") DBI db) {
this.db = db;
}

View File

@ -28,20 +28,20 @@ import monasca.api.domain.exception.EntityExistsException;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.common.Paged;
import monasca.api.domain.model.notificationmethod.NotificationMethod;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepository;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepo;
import monasca.api.domain.model.notificationmethod.NotificationMethodType;
import monasca.common.persistence.BeanMapper;
/**
* Notification method repository implementation.
*/
public class NotificationMethodMySqlRepositoryImpl implements NotificationMethodRepository {
public class NotificationMethodMySqlRepoImpl implements NotificationMethodRepo {
private static final Logger LOG = LoggerFactory
.getLogger(NotificationMethodMySqlRepositoryImpl.class);
.getLogger(NotificationMethodMySqlRepoImpl.class);
private final DBI db;
@Inject
public NotificationMethodMySqlRepositoryImpl(@Named("mysql") DBI db) {
public NotificationMethodMySqlRepoImpl(@Named("mysql") DBI db) {
this.db = db;
}

View File

@ -14,7 +14,6 @@
package monasca.api.infrastructure.persistence.vertica;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -32,7 +31,7 @@ import org.skife.jdbi.v2.Query;
import org.skife.jdbi.v2.util.StringMapper;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistory;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepository;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepo;
import monasca.api.infrastructure.persistence.DimensionQueries;
import monasca.api.infrastructure.persistence.SubAlarmDefinitionQueries;
import monasca.common.persistence.BeanMapper;
@ -40,7 +39,7 @@ import monasca.common.persistence.BeanMapper;
/**
* Alarm repository implementation.
*/
public class AlarmStateHistoryVerticaRepositoryImpl implements AlarmStateHistoryRepository {
public class AlarmStateHistoryVerticaRepoImpl implements AlarmStateHistoryRepo {
public static final DateTimeFormatter DATETIME_FORMATTER = ISODateTimeFormat.dateTimeNoMillis()
.withZoneUTC();
private static final String FIND_ALARMS_SQL =
@ -56,8 +55,7 @@ public class AlarmStateHistoryVerticaRepositoryImpl implements AlarmStateHistory
private final DBI vertica;
@Inject
public AlarmStateHistoryVerticaRepositoryImpl(@Named("mysql") DBI mysql,
@Named("vertica") DBI vertica) {
public AlarmStateHistoryVerticaRepoImpl(@Named("mysql") DBI mysql, @Named("vertica") DBI vertica) {
this.mysql = mysql;
this.vertica = vertica;
}

View File

@ -16,7 +16,6 @@ package monasca.api.infrastructure.persistence.vertica;
import java.nio.ByteBuffer;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -32,14 +31,14 @@ import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.Query;
import monasca.api.domain.model.measurement.MeasurementRepository;
import monasca.api.domain.model.measurement.MeasurementRepo;
import monasca.api.domain.model.measurement.Measurements;
import monasca.api.infrastructure.persistence.DimensionQueries;
/**
* Vertica measurement repository implementation.
*/
public class MeasurementVerticaRepositoryImpl implements MeasurementRepository {
public class MeasurementVerticaRepoImpl implements MeasurementRepo {
public static final DateTimeFormatter DATETIME_FORMATTER = ISODateTimeFormat.dateTimeNoMillis()
.withZoneUTC();
private static final String FIND_BY_METRIC_DEF_SQL =
@ -51,7 +50,7 @@ public class MeasurementVerticaRepositoryImpl implements MeasurementRepository {
private final DBI db;
@Inject
public MeasurementVerticaRepositoryImpl(@Named("vertica") DBI db) {
public MeasurementVerticaRepoImpl(@Named("vertica") DBI db) {
this.db = db;
}

View File

@ -27,13 +27,13 @@ import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.Query;
import monasca.common.model.metric.MetricDefinition;
import monasca.api.domain.model.metric.MetricDefinitionRepository;
import monasca.api.domain.model.metric.MetricDefinitionRepo;
import monasca.api.infrastructure.persistence.DimensionQueries;
/**
* Vertica metric definition repository implementation.
*/
public class MetricDefinitionVerticaRepositoryImpl implements MetricDefinitionRepository {
public class MetricDefinitionVerticaRepoImpl implements MetricDefinitionRepo {
private static final String FIND_BY_METRIC_DEF_SQL =
"select dd.id, def.name, d.name as dname, d.value as dvalue "
+ "from MonMetrics.Definitions def, MonMetrics.DefinitionDimensions dd "
@ -43,7 +43,7 @@ public class MetricDefinitionVerticaRepositoryImpl implements MetricDefinitionRe
private final DBI db;
@Inject
public MetricDefinitionVerticaRepositoryImpl(@Named("vertica") DBI db) {
public MetricDefinitionVerticaRepoImpl(@Named("vertica") DBI db) {
this.db = db;
}

View File

@ -31,14 +31,14 @@ import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.Query;
import monasca.api.domain.model.statistic.StatisticRepository;
import monasca.api.domain.model.statistic.StatisticRepo;
import monasca.api.domain.model.statistic.Statistics;
import monasca.api.infrastructure.persistence.DimensionQueries;
/**
* Vertica statistic repository implementation.
*/
public class StatisticVerticaRepositoryImpl implements StatisticRepository {
public class StatisticVerticaRepoImpl implements StatisticRepo {
public static final DateTimeFormatter DATETIME_FORMATTER = ISODateTimeFormat.dateTimeNoMillis()
.withZoneUTC();
private static final String FIND_BY_METRIC_DEF_SQL =
@ -50,7 +50,7 @@ public class StatisticVerticaRepositoryImpl implements StatisticRepository {
private final DBI db;
@Inject
public StatisticVerticaRepositoryImpl(@Named("vertica") DBI db) {
public StatisticVerticaRepoImpl(@Named("vertica") DBI db) {
this.db = db;
}

View File

@ -47,7 +47,7 @@ import monasca.api.app.command.UpdateAlarmDefinitionCommand;
import monasca.api.app.validation.AlarmValidation;
import monasca.api.app.validation.Validation;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
import monasca.api.resource.annotation.PATCH;
import monasca.common.model.alarm.AlarmExpression;
@ -57,12 +57,12 @@ import monasca.common.model.alarm.AlarmExpression;
@Path(AlarmDefinitionResource.ALARM_DEFINITIONS_PATH)
public class AlarmDefinitionResource {
private final AlarmDefinitionService service;
private final AlarmDefinitionRepository repo;
private final AlarmDefinitionRepo repo;
public final static String ALARM_DEFINITIONS = "alarm-definitions";
public final static String ALARM_DEFINITIONS_PATH = "/v2.0/" + ALARM_DEFINITIONS;
@Inject
public AlarmDefinitionResource(AlarmDefinitionService service, AlarmDefinitionRepository repo) {
public AlarmDefinitionResource(AlarmDefinitionService service, AlarmDefinitionRepo repo) {
this.service = service;
this.repo = repo;
}

View File

@ -21,7 +21,6 @@ import com.fasterxml.jackson.databind.JsonMappingException;
import org.hibernate.validator.constraints.NotEmpty;
import org.joda.time.DateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -44,9 +43,8 @@ import monasca.api.app.AlarmService;
import monasca.api.app.command.UpdateAlarmCommand;
import monasca.api.app.validation.Validation;
import monasca.api.domain.model.alarm.Alarm;
import monasca.api.domain.model.alarm.AlarmRepository;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistory;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepository;
import monasca.api.domain.model.alarm.AlarmRepo;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepo;
import monasca.api.resource.annotation.PATCH;
import monasca.common.model.alarm.AlarmState;
@ -56,12 +54,12 @@ import monasca.common.model.alarm.AlarmState;
@Path("/v2.0/alarms")
public class AlarmResource {
private final AlarmService service;
private final AlarmRepository repo;
private final AlarmStateHistoryRepository stateHistoryRepo;
private final AlarmRepo repo;
private final AlarmStateHistoryRepo stateHistoryRepo;
@Inject
public AlarmResource(AlarmService service, AlarmRepository repo,
AlarmStateHistoryRepository stateHistoryRepo) {
public AlarmResource(AlarmService service, AlarmRepo repo,
AlarmStateHistoryRepo stateHistoryRepo) {
this.service = service;
this.repo = repo;
this.stateHistoryRepo = stateHistoryRepo;

View File

@ -23,7 +23,7 @@ import javax.ws.rs.core.UriInfo;
import com.google.common.base.Preconditions;
import monasca.api.MonApiConfiguration;
import monasca.api.ApiConfig;
import monasca.api.domain.model.common.Paged;
import monasca.api.domain.model.measurement.Measurements;
import monasca.common.model.domain.common.AbstractEntity;
@ -38,7 +38,7 @@ public final class Links {
static boolean accessedViaHttps;
static {
MonApiConfiguration config = Injector.getInstance(MonApiConfiguration.class);
ApiConfig config = Injector.getInstance(ApiConfig.class);
if (config != null && config.accessedViaHttps != null)
accessedViaHttps = config.accessedViaHttps;
}

View File

@ -35,7 +35,7 @@ import javax.ws.rs.core.UriInfo;
import monasca.api.app.validation.Validation;
import monasca.api.domain.model.common.Paged;
import monasca.api.domain.model.measurement.MeasurementRepository;
import monasca.api.domain.model.measurement.MeasurementRepo;
import monasca.api.domain.model.measurement.Measurements;
/**
@ -44,10 +44,10 @@ import monasca.api.domain.model.measurement.Measurements;
@Path("/v2.0/metrics/measurements")
public class MeasurementResource {
private final MeasurementRepository repo;
private final MeasurementRepo repo;
@Inject
public MeasurementResource(MeasurementRepository repo) {
public MeasurementResource(MeasurementRepo repo) {
this.repo = repo;
}

View File

@ -38,11 +38,10 @@ import javax.ws.rs.core.UriInfo;
import monasca.api.app.MetricService;
import monasca.api.app.command.CreateMetricCommand;
import monasca.api.app.validation.Validation;
import monasca.api.domain.model.metric.MetricDefinitionRepository;
import monasca.api.domain.model.metric.MetricDefinitionRepo;
import monasca.api.resource.exception.Exceptions;
import monasca.common.model.Services;
import monasca.common.model.metric.Metric;
import monasca.common.model.metric.MetricDefinition;
/**
* Metric resource implementation.
@ -53,10 +52,10 @@ public class MetricResource {
private static final Splitter COMMA_SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults();
private final MetricService service;
private final MetricDefinitionRepository metricRepo;
private final MetricDefinitionRepo metricRepo;
@Inject
public MetricResource(MetricService service, MetricDefinitionRepository metricRepo) {
public MetricResource(MetricService service, MetricDefinitionRepo metricRepo) {
this.service = service;
this.metricRepo = metricRepo;
}

View File

@ -16,7 +16,6 @@ package monasca.api.resource;
import com.codahale.metrics.annotation.Timed;
import java.net.URI;
import java.util.List;
import javax.inject.Inject;
import javax.validation.Valid;
@ -37,17 +36,17 @@ import javax.ws.rs.core.UriInfo;
import monasca.api.app.command.CreateNotificationMethodCommand;
import monasca.api.domain.model.notificationmethod.NotificationMethod;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepository;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepo;
/**
* Notification Method resource implementation.
*/
@Path("/v2.0/notification-methods")
public class NotificationMethodResource {
private final NotificationMethodRepository repo;
private final NotificationMethodRepo repo;
@Inject
public NotificationMethodResource(NotificationMethodRepository repo) {
public NotificationMethodResource(NotificationMethodRepo repo) {
this.repo = repo;
}

View File

@ -33,7 +33,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import monasca.api.app.validation.Validation;
import monasca.api.domain.model.statistic.StatisticRepository;
import monasca.api.domain.model.statistic.StatisticRepo;
import monasca.api.domain.model.statistic.Statistics;
// import monasca.common.util.stats.Statistics;
@ -45,10 +45,10 @@ import monasca.api.domain.model.statistic.Statistics;
public class StatisticResource {
private static final Splitter COMMA_SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults();
private final StatisticRepository repo;
private final StatisticRepo repo;
@Inject
public StatisticResource(StatisticRepository repo) {
public StatisticResource(StatisticRepo repo) {
this.repo = repo;
}

View File

@ -27,7 +27,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import monasca.api.domain.model.version.Version;
import monasca.api.domain.model.version.VersionRepository;
import monasca.api.domain.model.version.VersionRepo;
/**
* Version resource implementation.
@ -35,10 +35,10 @@ import monasca.api.domain.model.version.VersionRepository;
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public class VersionResource {
private final VersionRepository repository;
private final VersionRepo repository;
@Inject
public VersionResource(VersionRepository repository) {
public VersionResource(VersionRepo repository) {
this.repository = repository;
}

View File

@ -30,14 +30,20 @@ mysql:
checkConnectionOnBorrow: true
databaseConfiguration:
# vertica | influxdb
# databaseType can be (vertica | influxdb)
databaseType: influxdb
# Uncomment if databaseType is influxDB
influxDB:
# version can be (V8 | V9)
# If noversion set then defaults to V8.
version: V8
# Used only if version is V9.
maxHttpConnections: 100
name: mon
replicationFactor: 1
url: http://192.168.10.4:8086
# url: http://10.10.10.2:8086
user: mon_api
password: password
@ -84,7 +90,7 @@ server:
logging:
# The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL.
level: INFO
level: debug
# Logger-specific levels.
loggers:

View File

@ -46,17 +46,17 @@ import org.mockito.stubbing.Answer;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import monasca.api.MonApiConfiguration;
import monasca.api.ApiConfig;
import monasca.api.app.AlarmDefinitionService.SubExpressions;
import monasca.api.app.command.UpdateAlarmDefinitionCommand;
import monasca.common.model.alarm.AlarmExpression;
import monasca.common.model.alarm.AlarmSubExpression;
import monasca.common.model.event.AlarmDefinitionUpdatedEvent;
import monasca.common.util.Serialization;
import monasca.api.domain.model.alarm.AlarmRepository;
import monasca.api.domain.model.alarm.AlarmRepo;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepository;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepo;
@Test
public class AlarmDefinitionServiceTest {
@ -67,19 +67,19 @@ public class AlarmDefinitionServiceTest {
final static String TENANT_ID = "bob";
AlarmDefinitionService service;
MonApiConfiguration config;
ApiConfig config;
Producer<String, String> producer;
AlarmDefinitionRepository repo;
NotificationMethodRepository notificationMethodRepo;
AlarmDefinitionRepo repo;
NotificationMethodRepo notificationMethodRepo;
@BeforeMethod
@SuppressWarnings("unchecked")
protected void beforeMethod() {
config = new MonApiConfiguration();
config = new ApiConfig();
producer = mock(Producer.class);
repo = mock(AlarmDefinitionRepository.class);
notificationMethodRepo = mock(NotificationMethodRepository.class);
AlarmRepository alarmRepo = mock(AlarmRepository.class);
repo = mock(AlarmDefinitionRepo.class);
notificationMethodRepo = mock(NotificationMethodRepo.class);
AlarmRepo alarmRepo = mock(AlarmRepo.class);
service = new AlarmDefinitionService(config, producer, repo, alarmRepo, notificationMethodRepo);
when(

View File

@ -14,7 +14,7 @@
package monasca.api.infrastructure.persistence.influxdb;
import monasca.api.MonApiConfiguration;
import monasca.api.ApiConfig;
import org.influxdb.InfluxDB;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
@ -25,21 +25,22 @@ import org.skife.jdbi.v2.DBI;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import scala.actors.threadpool.Arrays;
import static monasca.api.infrastructure.persistence.influxdb.InfluxV8Utils.buildAlarmsPart;
@Test
public class AlarmStateHistoryInfluxDbRepositoryImplTest {
public class InfluxV8AlarmStateHistoryRepoTest {
@Mock(name = "mysql")
private DBI mysql;
@Mock
private MonApiConfiguration monApiConfiguration;
private ApiConfig apiConfig;
@Mock
private InfluxDB influxDB;
@InjectMocks
private AlarmStateHistoryInfluxDbRepositoryImpl alarmStateHistoryInfluxDBRepository;
private InfluxV8AlarmStateHistoryRepo alarmStateHistoryInfluxDBRepository;
@BeforeMethod(alwaysRun = true)
public void initMocks() {
@ -69,8 +70,7 @@ public class AlarmStateHistoryInfluxDbRepositoryImplTest {
@SuppressWarnings("unchecked")
public void buildAlarmsPartTest() {
String er = " and ( alarm_id = 'id-1' or alarm_id = 'id-2' )";
String r = this.alarmStateHistoryInfluxDBRepository.buildAlarmsPart(Arrays.asList(new
String[]{"id-1", "id-2"}));
String r = buildAlarmsPart(Arrays.asList(new String[]{"id-1", "id-2"}));
assert (er.equals(r));
}

View File

@ -25,26 +25,26 @@ import java.util.Map;
import java.util.regex.Pattern;
@Test
public class UtilsTest {
public class InfluxV8UtilsTest {
public void SQLSanitizerSanitizeGoodDataTest() throws Exception {
String goodString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "-_" +
".?/%=&鱼鸟";
assert (goodString.equals(Utils.SQLSanitizer.sanitize(goodString)));
assert (goodString.equals(InfluxV8Utils.SQLSanitizer.sanitize(goodString)));
}
@Test(expectedExceptions = {Exception.class})
public void SQLSanitizerSanitizeBadDataTest1() throws Exception {
String badStringWithSemicolon = "abcdefghijklmnopqrs;tuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "-_.";
assert (badStringWithSemicolon.equals(Utils.SQLSanitizer.sanitize(badStringWithSemicolon)));
assert (badStringWithSemicolon.equals(InfluxV8Utils.SQLSanitizer.sanitize(badStringWithSemicolon)));
}
@Test(expectedExceptions = {Exception.class})
public void SQLSanitizerSanitizeBadDataTest2() throws Exception {
String badStringWithSingleQuote = "'a'bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "-_.";
assert (badStringWithSingleQuote.equals(Utils.SQLSanitizer.sanitize(badStringWithSingleQuote)));
assert (badStringWithSingleQuote.equals(InfluxV8Utils.SQLSanitizer.sanitize(badStringWithSingleQuote)));
}
public void whereClauseBuilderBuildTimePartTest() {
@ -52,7 +52,7 @@ public class UtilsTest {
DateTime startTime = new DateTime(2014, 01, 01, 01, 01, 01, DateTimeZone.UTC);
DateTime endTime = new DateTime(2014, 01, 01, 01, 01, 02, DateTimeZone.UTC);
assert (expectedResult.equals(Utils.WhereClauseBuilder.buildTimePart(startTime, endTime)));
assert (expectedResult.equals(InfluxV8Utils.WhereClauseBuilder.buildTimePart(startTime, endTime)));
}
public void testBuildSerieNameRegex() throws Exception {
@ -63,12 +63,12 @@ public class UtilsTest {
// This doesn't ensure that influxdb will evaluate this correctly because it is written in GO, but it
// should give a good idea of the likelihood of success
checkRegex(Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_perc", null), seriesNoDims, true);
checkRegex(Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_perc", null), seriesWithDims, true);
checkRegex(InfluxV8Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_perc", null), seriesNoDims, true);
checkRegex(InfluxV8Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_perc", null), seriesWithDims, true);
// There was a bug where it was effectively doing a "startsWith" instead of pure match so test that
checkRegex(Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_per", null), seriesNoDims, false);
checkRegex(Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_per", null), seriesWithDims, false);
checkRegex(InfluxV8Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_per", null), seriesNoDims, false);
checkRegex(InfluxV8Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_per", null), seriesWithDims, false);
// Make sure it works with the dimension to find in the front, middle and end of the dimensions
// and that it does an exact match
@ -81,10 +81,10 @@ public class UtilsTest {
String name, String goodValue, String badValue) throws Exception {
final Map<String, String> dimensions = new HashMap<String, String>();
dimensions.put(name, goodValue);
checkRegex(Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_perc", dimensions), seriesWithDims, true);
checkRegex(InfluxV8Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_perc", dimensions), seriesWithDims, true);
dimensions.put(name, badValue);
checkRegex(Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_perc", dimensions), seriesWithDims, false);
checkRegex(InfluxV8Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_perc", dimensions), seriesWithDims, false);
}
private void checkRegex(String regex, final String seriesNoDims, final boolean expected) {

View File

@ -45,13 +45,13 @@ import monasca.common.model.alarm.AlarmSubExpression;
import monasca.common.model.metric.MetricDefinition;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
@Test(groups = "database")
public class AlarmDefinitionMySqlRepositoryImplTest {
private DBI db;
private Handle handle;
private AlarmDefinitionRepository repo;
private AlarmDefinitionRepo repo;
private List<String> alarmActions;
private AlarmDefinition alarmDef_123;
private AlarmDefinition alarmDef_234;
@ -62,7 +62,7 @@ public class AlarmDefinitionMySqlRepositoryImplTest {
handle = db.open();
handle
.execute(Resources.toString(getClass().getResource("alarm.sql"), Charset.defaultCharset()));
repo = new AlarmDefinitionMySqlRepositoryImpl(db);
repo = new AlarmDefinitionMySqlRepoImpl(db);
alarmActions = new ArrayList<String>();
alarmActions.add("29387234");
@ -154,7 +154,7 @@ public class AlarmDefinitionMySqlRepositoryImplTest {
// Warning, this will truncate your mini-mon database
db = new DBI("jdbc:mysql://192.168.10.4/mon", "monapi", "password");
handle = db.open();
repo = new AlarmDefinitionMySqlRepositoryImpl(db);
repo = new AlarmDefinitionMySqlRepoImpl(db);
beforeMethod();
List<String> oldSubAlarmIds = Arrays.asList("222");
@ -198,7 +198,7 @@ public class AlarmDefinitionMySqlRepositoryImplTest {
// Warning, this will truncate your mini-mon database
db = new DBI("jdbc:mysql://192.168.10.4/mon", "monapi", "password");
handle = db.open();
repo = new AlarmDefinitionMySqlRepositoryImpl(db);
repo = new AlarmDefinitionMySqlRepoImpl(db);
beforeMethod();
assertEquals(
@ -221,7 +221,7 @@ public class AlarmDefinitionMySqlRepositoryImplTest {
// Warning, this will truncate your mini-mon database
db = new DBI("jdbc:mysql://192.168.10.4/mon", "monapi", "password");
handle = db.open();
repo = new AlarmDefinitionMySqlRepositoryImpl(db);
repo = new AlarmDefinitionMySqlRepoImpl(db);
beforeMethod();
assertEquals(

View File

@ -23,7 +23,7 @@ import com.google.common.collect.ImmutableMap.Builder;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.alarm.Alarm;
import monasca.api.domain.model.alarm.AlarmRepository;
import monasca.api.domain.model.alarm.AlarmRepo;
import monasca.common.model.alarm.AlarmState;
import monasca.common.model.alarm.AlarmSubExpression;
import monasca.common.model.metric.MetricDefinition;
@ -53,7 +53,7 @@ public class AlarmMySqlRepositoryImplTest {
private static final String ALARM_ID = "234111";
private DBI db;
private Handle handle;
private AlarmRepository repo;
private AlarmRepo repo;
private List<String> alarmActions;
private Alarm compoundAlarm;
private Alarm alarm1;
@ -71,7 +71,7 @@ public class AlarmMySqlRepositoryImplTest {
handle
.execute(Resources.toString(getClass().getResource("alarm.sql"), Charset.defaultCharset()));
*/
repo = new AlarmMySqlRepositoryImpl(db);
repo = new AlarmMySqlRepoImpl(db);
alarmActions = new ArrayList<String>();
alarmActions.add("29387234");

View File

@ -34,13 +34,12 @@ import com.google.common.io.Resources;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.notificationmethod.NotificationMethod;
import monasca.api.domain.model.notificationmethod.NotificationMethodType;
import monasca.api.infrastructure.persistence.mysql.NotificationMethodMySqlRepositoryImpl;
@Test
public class NotificationMethodMySqlRepositoryImplTest {
private DBI db;
private Handle handle;
private NotificationMethodMySqlRepositoryImpl repo;
private NotificationMethodMySqlRepoImpl repo;
@BeforeClass
protected void beforeClass() throws Exception {
@ -48,7 +47,7 @@ public class NotificationMethodMySqlRepositoryImplTest {
handle = db.open();
handle.execute(Resources.toString(getClass().getResource("notification_method.sql"),
Charset.defaultCharset()));
repo = new NotificationMethodMySqlRepositoryImpl(db);
repo = new NotificationMethodMySqlRepoImpl(db);
}
@AfterClass

View File

@ -15,8 +15,7 @@
package monasca.api.infrastructure.persistence.vertica;
import monasca.common.model.alarm.AlarmState;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepository;
import monasca.api.infrastructure.persistence.vertica.AlarmStateHistoryVerticaRepositoryImpl;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepo;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.DBI;
@ -34,14 +33,14 @@ import static org.testng.Assert.assertEquals;
public class AlarmStateHistoryVerticaRepositoryImplTest {
private DBI db;
private Handle handle;
private AlarmStateHistoryRepository repo;
private AlarmStateHistoryRepo repo;
@BeforeClass
protected void setupClass() throws Exception {
Class.forName("com.vertica.jdbc.Driver");
db = new DBI("jdbc:vertica://192.168.10.4/mon", "dbadmin", "password");
handle = db.open();
repo = new AlarmStateHistoryVerticaRepositoryImpl(null, db);
repo = new AlarmStateHistoryVerticaRepoImpl(null, db);
}
@AfterClass

View File

@ -14,9 +14,8 @@
package monasca.api.infrastructure.persistence.vertica;
import monasca.api.domain.model.measurement.MeasurementRepository;
import monasca.api.domain.model.measurement.MeasurementRepo;
import monasca.api.domain.model.measurement.Measurements;
import monasca.api.infrastructure.persistence.vertica.MeasurementVerticaRepositoryImpl;
import org.joda.time.DateTime;
import org.skife.jdbi.v2.DBI;
@ -36,14 +35,14 @@ import static org.testng.Assert.assertEquals;
public class MeasurementVerticaRepositoryImplTest {
private DBI db;
private Handle handle;
private MeasurementRepository repo;
private MeasurementRepo repo;
@BeforeClass
protected void setupClass() throws Exception {
Class.forName("com.vertica.jdbc.Driver");
db = new DBI("jdbc:vertica://192.168.10.4/mon", "dbadmin", "password");
handle = db.open();
repo = new MeasurementVerticaRepositoryImpl(db);
repo = new MeasurementVerticaRepoImpl(db);
}
@AfterClass

View File

@ -15,8 +15,7 @@
package monasca.api.infrastructure.persistence.vertica;
import monasca.common.model.metric.MetricDefinition;
import monasca.api.domain.model.metric.MetricDefinitionRepository;
import monasca.api.infrastructure.persistence.vertica.MetricDefinitionVerticaRepositoryImpl;
import monasca.api.domain.model.metric.MetricDefinitionRepo;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
@ -35,14 +34,14 @@ import static org.testng.Assert.assertEquals;
public class MetricDefinitionVerticaRepositoryImplTest {
private DBI db;
private Handle handle;
private MetricDefinitionRepository repo;
private MetricDefinitionRepo repo;
@BeforeClass
protected void setupClass() throws Exception {
Class.forName("com.vertica.jdbc.Driver");
db = new DBI("jdbc:vertica://192.168.10.4/mon", "dbadmin", "password");
handle = db.open();
repo = new MetricDefinitionVerticaRepositoryImpl(db);
repo = new MetricDefinitionVerticaRepoImpl(db);
}
@AfterClass

View File

@ -42,17 +42,17 @@ import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
import monasca.api.MonApiConfiguration;
import monasca.api.ApiConfig;
import monasca.api.MonApiModule;
import monasca.api.app.AlarmDefinitionService;
import monasca.api.app.command.CreateAlarmDefinitionCommand;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepository;
import monasca.api.infrastructure.persistence.mysql.AlarmDefinitionMySqlRepositoryImpl;
import monasca.api.infrastructure.persistence.mysql.AlarmMySqlRepositoryImpl;
import monasca.api.infrastructure.persistence.mysql.NotificationMethodMySqlRepositoryImpl;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistoryRepo;
import monasca.api.infrastructure.persistence.mysql.AlarmDefinitionMySqlRepoImpl;
import monasca.api.infrastructure.persistence.mysql.AlarmMySqlRepoImpl;
import monasca.api.infrastructure.persistence.mysql.NotificationMethodMySqlRepoImpl;
import monasca.api.resource.AbstractMonApiResourceTest;
import monasca.api.resource.AlarmDefinitionResource;
import com.sun.jersey.api.client.ClientResponse;
@ -63,10 +63,10 @@ public class AlarmIntegrationTest extends AbstractMonApiResourceTest {
private DBI mysqlDb;
private AlarmDefinition alarm;
private AlarmDefinitionService service;
private MonApiConfiguration config;
private ApiConfig config;
private Producer<String, String> producer;
private AlarmDefinitionRepository repo;
AlarmStateHistoryRepository stateHistoryRepo;
private AlarmDefinitionRepo repo;
AlarmStateHistoryRepo stateHistoryRepo;
private Map<String, String> dimensions;
private List<String> alarmActions;
@ -83,25 +83,25 @@ public class AlarmIntegrationTest extends AbstractMonApiResourceTest {
.execute("insert into notification_method (id, tenant_id, name, type, address, created_at, updated_at) values ('77778687', 'alarm-test', 'MyEmail', 'EMAIL', 'a@b', NOW(), NOW())");
mysqlDb.close(handle);
repo = new AlarmDefinitionMySqlRepositoryImpl(mysqlDb);
repo = new AlarmDefinitionMySqlRepoImpl(mysqlDb);
service =
new AlarmDefinitionService(config, producer, repo, new AlarmMySqlRepositoryImpl(mysqlDb),
new NotificationMethodMySqlRepositoryImpl(mysqlDb));
new AlarmDefinitionService(config, producer, repo, new AlarmMySqlRepoImpl(mysqlDb),
new NotificationMethodMySqlRepoImpl(mysqlDb));
addResources(new AlarmDefinitionResource(service, repo));
}
@BeforeTest
protected void beforeTest() throws Exception {
config = getConfiguration("config-test.yml", MonApiConfiguration.class);
config = getConfiguration("config-test.yml", ApiConfig.class);
Injector injector = Guice.createInjector(new MonApiModule(environment, config));
producer = injector.getInstance(Key.get(new TypeLiteral<Producer<String, String>>() {}));
mysqlDb = injector.getInstance(Key.get(DBI.class, Names.named("mysql")));
Handle handle = mysqlDb.open();
handle.execute(Resources.toString(
NotificationMethodMySqlRepositoryImpl.class.getResource("alarm.sql"),
NotificationMethodMySqlRepoImpl.class.getResource("alarm.sql"),
Charset.defaultCharset()));
handle.execute(Resources.toString(
NotificationMethodMySqlRepositoryImpl.class.getResource("notification_method.sql"),
NotificationMethodMySqlRepoImpl.class.getResource("notification_method.sql"),
Charset.defaultCharset()));
handle.close();

View File

@ -34,11 +34,11 @@ import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import monasca.api.MonApiConfiguration;
import monasca.api.ApiConfig;
import monasca.api.MonApiModule;
import monasca.api.app.MetricService;
import monasca.api.app.command.CreateMetricCommand;
import monasca.api.domain.model.metric.MetricDefinitionRepository;
import monasca.api.domain.model.metric.MetricDefinitionRepo;
import monasca.api.resource.AbstractMonApiResourceTest;
import monasca.api.resource.MetricResource;
import com.sun.jersey.api.client.ClientResponse;
@ -49,8 +49,8 @@ public class MetricIntegrationTest extends AbstractMonApiResourceTest {
private DBI db;
private MetricService service;
private Producer<String, String> producer;
private MonApiConfiguration config;
private MetricDefinitionRepository metricRepo;
private ApiConfig config;
private MetricDefinitionRepo metricRepo;
private Map<String, String> dimensions;
@Override
@ -59,14 +59,14 @@ public class MetricIntegrationTest extends AbstractMonApiResourceTest {
Handle handle = db.open();
handle.execute("truncate table access");
db.close(handle);
metricRepo = mock(MetricDefinitionRepository.class);
metricRepo = mock(MetricDefinitionRepo.class);
service = new MetricService(config, producer, metricRegistry);
addResources(new MetricResource(service, metricRepo));
}
@BeforeTest
protected void beforeTest() throws Exception {
config = getConfiguration("config-test.yml", MonApiConfiguration.class);
config = getConfiguration("config-test.yml", ApiConfig.class);
Injector injector = Guice.createInjector(new MonApiModule(environment, config));
producer = injector.getInstance(Key.get(new TypeLiteral<Producer<String, String>>() {}));
}

View File

@ -31,14 +31,14 @@ import org.testng.annotations.Test;
import com.google.common.io.Resources;
import com.google.inject.Guice;
import com.google.inject.Injector;
import monasca.api.MonApiConfiguration;
import monasca.api.ApiConfig;
import monasca.api.MonApiModule;
import monasca.api.app.command.CreateNotificationMethodCommand;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.notificationmethod.NotificationMethod;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepository;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepo;
import monasca.api.domain.model.notificationmethod.NotificationMethodType;
import monasca.api.infrastructure.persistence.mysql.NotificationMethodMySqlRepositoryImpl;
import monasca.api.infrastructure.persistence.mysql.NotificationMethodMySqlRepoImpl;
import monasca.api.resource.AbstractMonApiResourceTest;
import monasca.api.resource.NotificationMethodResource;
import com.sun.jersey.api.client.ClientResponse;
@ -48,7 +48,7 @@ public class NotificationMethodIntegrationTest extends AbstractMonApiResourceTes
private static final String TENANT_ID = "notification-method-test";
private DBI db;
private NotificationMethod notificationMethod;
private NotificationMethodRepository repo;
private NotificationMethodRepo repo;
@Override
protected void setupResources() throws Exception {
@ -59,18 +59,18 @@ public class NotificationMethodIntegrationTest extends AbstractMonApiResourceTes
.execute("insert into notification_method (id, tenant_id, name, type, address, created_at, updated_at) values ('29387234', 'notification-method-test', 'MyEmaila', 'EMAIL', 'a@b', NOW(), NOW())");
db.close(handle);
repo = new NotificationMethodMySqlRepositoryImpl(db);
repo = new NotificationMethodMySqlRepoImpl(db);
addResources(new NotificationMethodResource(repo));
}
@BeforeTest
protected void beforeTest() throws Exception {
MonApiConfiguration config = getConfiguration("config-test.yml", MonApiConfiguration.class);
ApiConfig config = getConfiguration("config-test.yml", ApiConfig.class);
Injector injector = Guice.createInjector(new MonApiModule(environment, config));
db = injector.getInstance(DBI.class);
Handle handle = db.open();
handle.execute(Resources.toString(
NotificationMethodMySqlRepositoryImpl.class.getResource("notification_method.sql"),
NotificationMethodMySqlRepoImpl.class.getResource("notification_method.sql"),
Charset.defaultCharset()));
handle.close();

View File

@ -43,7 +43,7 @@ import monasca.api.app.command.UpdateAlarmDefinitionCommand;
import monasca.common.model.alarm.AlarmExpression;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
import monasca.api.domain.model.common.Link;
import monasca.api.resource.exception.ErrorMessages;
import com.sun.jersey.api.client.ClientResponse;
@ -55,7 +55,7 @@ public class AlarmDefinitionResourceTest extends AbstractMonApiResourceTest {
private AlarmDefinition alarm;
private AlarmDefinition alarmItem;
private AlarmDefinitionService service;
private AlarmDefinitionRepository repo;
private AlarmDefinitionRepo repo;
private List<String> alarmActions;
@Override
@ -81,7 +81,7 @@ public class AlarmDefinitionResourceTest extends AbstractMonApiResourceTest {
eq(expression), eq(AlarmExpression.of(expression)), eq(matchBy), any(List.class),
any(List.class), any(List.class))).thenReturn(alarm);
repo = mock(AlarmDefinitionRepository.class);
repo = mock(AlarmDefinitionRepo.class);
when(repo.findById(eq("abc"), eq("123"))).thenReturn(alarm);
when(repo.find(anyString(), anyString(), (Map<String, String>) anyMap(), anyString())).thenReturn(
Arrays.asList(alarmItem));

View File

@ -34,7 +34,7 @@ import org.testng.annotations.Test;
import monasca.api.app.MetricService;
import monasca.api.app.command.CreateMetricCommand;
import monasca.api.domain.model.metric.MetricDefinitionRepository;
import monasca.api.domain.model.metric.MetricDefinitionRepo;
import monasca.api.resource.exception.ErrorMessages;
import com.sun.jersey.api.client.ClientResponse;
@ -42,7 +42,7 @@ import com.sun.jersey.api.client.ClientResponse;
public class MetricResourceTest extends AbstractMonApiResourceTest {
private Map<String, String> dimensions;
private MetricService service;
private MetricDefinitionRepository metricRepo;
private MetricDefinitionRepo metricRepo;
long timestamp;
@Override
@ -57,7 +57,7 @@ public class MetricResourceTest extends AbstractMonApiResourceTest {
service = mock(MetricService.class);
doNothing().when(service).create(any(List.class), anyString(), anyString());
metricRepo = mock(MetricDefinitionRepository.class);
metricRepo = mock(MetricDefinitionRepo.class);
addResources(new MetricResource(service, metricRepo));
}

View File

@ -19,7 +19,7 @@ import com.sun.jersey.api.client.GenericType;
import monasca.api.app.command.CreateNotificationMethodCommand;
import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.notificationmethod.NotificationMethod;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepository;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepo;
import monasca.api.domain.model.notificationmethod.NotificationMethodType;
import monasca.api.resource.exception.ErrorMessages;
import org.testng.annotations.Test;
@ -37,7 +37,7 @@ import static org.testng.Assert.*;
@Test
public class NotificationMethodResourceTest extends AbstractMonApiResourceTest {
private NotificationMethod notificationMethod, notificationMethodWebhook, notificationMethodPagerduty;
private NotificationMethodRepository repo;
private NotificationMethodRepo repo;
@Override
protected void setupResources() throws Exception {
@ -49,7 +49,7 @@ public class NotificationMethodResourceTest extends AbstractMonApiResourceTest {
notificationMethodPagerduty =
new NotificationMethod("12345", "MyPd", NotificationMethodType.PAGERDUTY, "nzH2LVRdMzun11HNC2oD");
repo = mock(NotificationMethodRepository.class);
repo = mock(NotificationMethodRepo.class);
when(repo.create(eq("abc"), eq("MyEmail"), eq(NotificationMethodType.EMAIL), anyString()))
.thenReturn(notificationMethod);
when(repo.create(eq("abc"), eq("MyWh"), eq(NotificationMethodType.WEBHOOK), anyString()))

View File

@ -27,19 +27,19 @@ import java.util.Map;
import org.joda.time.DateTime;
import org.testng.annotations.Test;
import monasca.api.domain.model.statistic.StatisticRepository;
import monasca.api.domain.model.statistic.StatisticRepo;
import com.sun.jersey.api.client.ClientResponse;
@Test
public class StatisticResourceTest extends AbstractMonApiResourceTest {
private StatisticRepository statisticRepo;
private StatisticRepo statisticRepo;
long timestamp;
@Override
protected void setupResources() throws Exception {
super.setupResources();
statisticRepo = mock(StatisticRepository.class);
statisticRepo = mock(StatisticRepo.class);
addResources(new StatisticResource(statisticRepo));
}

View File

@ -34,13 +34,13 @@ import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.common.Link;
import monasca.api.domain.model.version.Version;
import monasca.api.domain.model.version.Version.VersionStatus;
import monasca.api.domain.model.version.VersionRepository;
import monasca.api.domain.model.version.VersionRepo;
import com.sun.jersey.api.client.GenericType;
@Test
public class VersionResourceTest extends AbstractMonApiResourceTest {
private Version version;
private VersionRepository repo;
private VersionRepo repo;
@Override
protected void setupResources() throws Exception {
@ -49,7 +49,7 @@ public class VersionResourceTest extends AbstractMonApiResourceTest {
version.setLinks(Arrays.asList(new Link("self",
"https://cloudsvc.example.com/v2.0")));
repo = mock(VersionRepository.class);
repo = mock(VersionRepo.class);
when(repo.findById(eq("v2.0"))).thenReturn(version);
when(repo.find()).thenReturn(Arrays.asList(version));
addResources(new VersionResource(repo));