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> <version>6.8.8</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

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

View File

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

View File

@ -41,17 +41,17 @@ import monasca.api.infrastructure.InfrastructureModule;
* Monitoring API server bindings. * Monitoring API server bindings.
*/ */
public class MonApiModule extends AbstractModule { public class MonApiModule extends AbstractModule {
private final MonApiConfiguration config; private final ApiConfig config;
private final Environment environment; private final Environment environment;
public MonApiModule(Environment environment, MonApiConfiguration config) { public MonApiModule(Environment environment, ApiConfig config) {
this.environment = environment; this.environment = environment;
this.config = config; this.config = config;
} }
@Override @Override
protected void configure() { protected void configure() {
bind(MonApiConfiguration.class).toInstance(config); bind(ApiConfig.class).toInstance(config);
bind(MetricRegistry.class).toInstance(environment.metrics()); bind(MetricRegistry.class).toInstance(environment.metrics());
bind(DataSourceFactory.class).annotatedWith(Names.named("mysql")).toInstance(config.mysql); bind(DataSourceFactory.class).annotatedWith(Names.named("mysql")).toInstance(config.mysql);
bind(DataSourceFactory.class).annotatedWith(Names.named("vertica")).toInstance(config.vertica); 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.HashBiMap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import monasca.api.MonApiConfiguration; import monasca.api.ApiConfig;
import monasca.api.app.command.UpdateAlarmDefinitionCommand; import monasca.api.app.command.UpdateAlarmDefinitionCommand;
import monasca.common.model.event.AlarmDefinitionCreatedEvent; import monasca.common.model.event.AlarmDefinitionCreatedEvent;
import monasca.common.model.event.AlarmDefinitionDeletedEvent; 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.EntityNotFoundException;
import monasca.api.domain.exception.InvalidEntityException; import monasca.api.domain.exception.InvalidEntityException;
import monasca.api.domain.model.alarm.Alarm; 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.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository; import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
import monasca.api.domain.model.notificationmethod.NotificationMethodRepository; import monasca.api.domain.model.notificationmethod.NotificationMethodRepo;
import monasca.common.util.Exceptions; import monasca.common.util.Exceptions;
import monasca.common.util.Serialization; import monasca.common.util.Serialization;
@ -60,17 +60,17 @@ import monasca.common.util.Serialization;
public class AlarmDefinitionService { public class AlarmDefinitionService {
private static final Logger LOG = LoggerFactory.getLogger(AlarmService.class); 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 Producer<String, String> producer;
private final AlarmDefinitionRepository repo; private final AlarmDefinitionRepo repo;
private final AlarmRepository alarmRepo; private final AlarmRepo alarmRepo;
private final NotificationMethodRepository notificationMethodRepo; private final NotificationMethodRepo notificationMethodRepo;
long eventCount; long eventCount;
@Inject @Inject
public AlarmDefinitionService(MonApiConfiguration config, Producer<String, String> producer, public AlarmDefinitionService(ApiConfig config, Producer<String, String> producer,
AlarmDefinitionRepository repo, AlarmRepository alarmRepo, AlarmDefinitionRepo repo, AlarmRepo alarmRepo,
NotificationMethodRepository notificationMethodRepo) { NotificationMethodRepo notificationMethodRepo) {
this.config = config; this.config = config;
this.producer = producer; this.producer = producer;
this.repo = repo; this.repo = repo;

View File

@ -23,7 +23,7 @@ import kafka.producer.KeyedMessage;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import monasca.api.MonApiConfiguration; import monasca.api.ApiConfig;
import monasca.api.app.command.UpdateAlarmCommand; import monasca.api.app.command.UpdateAlarmCommand;
import monasca.common.model.event.AlarmDeletedEvent; import monasca.common.model.event.AlarmDeletedEvent;
import monasca.common.model.event.AlarmStateTransitionedEvent; 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.EntityNotFoundException;
import monasca.api.domain.exception.InvalidEntityException; import monasca.api.domain.exception.InvalidEntityException;
import monasca.api.domain.model.alarm.Alarm; 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.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository; import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
import monasca.common.util.Exceptions; import monasca.common.util.Exceptions;
import monasca.common.util.Serialization; import monasca.common.util.Serialization;
@ -45,15 +45,15 @@ import monasca.common.util.Serialization;
public class AlarmService { public class AlarmService {
private static final Logger LOG = LoggerFactory.getLogger(AlarmService.class); 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 Producer<String, String> producer;
private final AlarmRepository repo; private final AlarmRepo repo;
private final AlarmDefinitionRepository alarmDefRepo; private final AlarmDefinitionRepo alarmDefRepo;
private long messageCount = 0; private long messageCount = 0;
@Inject @Inject
public AlarmService(MonApiConfiguration config, Producer<String, String> producer, public AlarmService(ApiConfig config, Producer<String, String> producer,
AlarmRepository repo, AlarmDefinitionRepository alarmDefRepo) { AlarmRepo repo, AlarmDefinitionRepo alarmDefRepo) {
this.config = config; this.config = config;
this.producer = producer; this.producer = producer;
this.repo = repo; 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;
import com.google.common.collect.ImmutableMap.Builder; 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.Metric;
import monasca.common.model.metric.MetricEnvelope; import monasca.common.model.metric.MetricEnvelope;
import monasca.common.model.metric.MetricEnvelopes; import monasca.common.model.metric.MetricEnvelopes;
@ -41,13 +41,13 @@ import monasca.common.model.metric.MetricEnvelopes;
* Metric service implementation. * Metric service implementation.
*/ */
public class MetricService { public class MetricService {
private final MonApiConfiguration config; private final ApiConfig config;
private final Producer<String, String> producer; private final Producer<String, String> producer;
private final Meter metricMeter; private final Meter metricMeter;
private final Meter batchMeter; private final Meter batchMeter;
@Inject @Inject
public MetricService(MonApiConfiguration config, Producer<String, String> producer, public MetricService(ApiConfig config, Producer<String, String> producer,
MetricRegistry metricRegistry) { MetricRegistry metricRegistry) {
this.config = config; this.config = config;
this.producer = producer; this.producer = producer;

View File

@ -16,8 +16,8 @@ package monasca.api.domain;
import javax.inject.Singleton; import javax.inject.Singleton;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import monasca.api.domain.model.version.VersionRepository; import monasca.api.domain.model.version.VersionRepo;
import monasca.api.domain.service.impl.VersionRepositoryImpl; import monasca.api.domain.service.impl.VersionRepoImpl;
/** /**
* Domain layer bindings. * Domain layer bindings.
@ -25,6 +25,6 @@ import monasca.api.domain.service.impl.VersionRepositoryImpl;
public class DomainModule extends AbstractModule { public class DomainModule extends AbstractModule {
@Override @Override
protected void configure() { 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.common.model.alarm.AlarmSubExpression;
import monasca.api.domain.exception.EntityNotFoundException; import monasca.api.domain.exception.EntityNotFoundException;
public interface AlarmRepository { public interface AlarmRepo {
/** /**
* Deletes all alarms associated with the {@code id}. * Deletes all alarms associated with the {@code id}.
*/ */

View File

@ -24,7 +24,7 @@ import monasca.api.domain.exception.EntityNotFoundException;
/** /**
* Repository for alarm definitions. * Repository for alarm definitions.
*/ */
public interface AlarmDefinitionRepository { public interface AlarmDefinitionRepo {
/** /**
* Creates and returns a new alarm definition for the criteria. * 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. * Repository for alarm state history.
*/ */
public interface AlarmStateHistoryRepository { public interface AlarmStateHistoryRepo {
/** /**
* @throws EntityNotFoundException if an alarm cannot be found for the {@code alarmId} * @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. * Repository for measurements.
*/ */
public interface MeasurementRepository { public interface MeasurementRepo {
/** /**
* Finds measurements for the given criteria. * Finds measurements for the given criteria.
*/ */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,12 +22,12 @@ import org.joda.time.DateTimeZone;
import monasca.api.domain.exception.EntityNotFoundException; import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.version.Version; import monasca.api.domain.model.version.Version;
import monasca.api.domain.model.version.Version.VersionStatus; 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. * 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( private static final Version v2_0 = new Version("v2.0", VersionStatus.CURRENT, new DateTime(
DateTimeZone.UTC)); DateTimeZone.UTC));

View File

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

View File

@ -13,7 +13,6 @@
*/ */
package monasca.api.infrastructure.persistence.influxdb; package monasca.api.infrastructure.persistence.influxdb;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -39,26 +38,27 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.google.inject.Inject; import com.google.inject.Inject;
import monasca.api.MonApiConfiguration; import monasca.api.ApiConfig;
import monasca.api.domain.model.common.Paged;
import monasca.common.model.alarm.AlarmState; import monasca.common.model.alarm.AlarmState;
import monasca.common.model.metric.MetricDefinition; import monasca.common.model.metric.MetricDefinition;
import monasca.api.domain.model.alarmstatehistory.AlarmStateHistory; 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.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 ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private static final TypeReference<List<MetricDefinition>> METRICS_TYPE = private static final TypeReference<List<MetricDefinition>> METRICS_TYPE =
new TypeReference<List<MetricDefinition>>() {}; new TypeReference<List<MetricDefinition>>() {};
private static final Logger logger = LoggerFactory private static final Logger logger = LoggerFactory
.getLogger(AlarmStateHistoryInfluxDbRepositoryImpl.class); .getLogger(InfluxV8AlarmStateHistoryRepo.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 " + private final ApiConfig config;
"%s " +
"where ad.tenant_id = :tenantId and ad.deleted_at is NULL order by ad.created_at";
private final MonApiConfiguration config;
private final InfluxDB influxDB; private final InfluxDB influxDB;
private final DBI mysql; private final DBI mysql;
@ -68,8 +68,8 @@ public class AlarmStateHistoryInfluxDbRepositoryImpl implements AlarmStateHistor
} }
@Inject @Inject
public AlarmStateHistoryInfluxDbRepositoryImpl(@Named("mysql") DBI mysql, public InfluxV8AlarmStateHistoryRepo(@Named("mysql") DBI mysql, ApiConfig config,
MonApiConfiguration config, InfluxDB influxDB) { InfluxDB influxDB) {
this.mysql = mysql; this.mysql = mysql;
this.config = config; this.config = config;
this.influxDB = influxDB; this.influxDB = influxDB;
@ -83,37 +83,27 @@ public class AlarmStateHistoryInfluxDbRepositoryImpl implements AlarmStateHistor
} }
String buildQueryForFindById(String tenantId, String alarmId, String offset) throws Exception { 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 " 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", + "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 @Override
public List<AlarmStateHistory> find(String tenantId, Map<String, String> dimensions, public List<AlarmStateHistory> find(String tenantId, Map<String, String> dimensions,
DateTime startTime, @Nullable DateTime endTime, String offset) throws Exception { DateTime startTime, @Nullable DateTime endTime, String offset) throws Exception {
List<String> alarmIds = null; List<String> alarmIdList = findAlarmIds(this.mysql, tenantId, dimensions);
// Find alarm Ids for dimensions
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); if (alarmIdList == null || alarmIdList.isEmpty()) {
logger.debug("AlarmStateHistory query '{}'", sql);
DimensionQueries.bindDimensionsToQuery(query, dimensions);
alarmIds = query.map(StringMapper.FIRST).list();
}
if (alarmIds == null || alarmIds.isEmpty()) {
logger.debug("AlarmStateHistory no alarmIds"); logger.debug("AlarmStateHistory no alarmIds");
return Collections.emptyList(); return Collections.emptyList();
} }
logger.debug("AlarmStateHistory alarmIds {}", alarmIds); logger.debug("AlarmStateHistory alarmIds {}", alarmIdList);
String timePart = buildTimePart(startTime, endTime); String timePart = buildTimePart(startTime, endTime);
String alarmsPart = buildAlarmsPart(alarmIds); String alarmsPart = buildAlarmsPart(alarmIdList);
String offsetPart = Utils.buildOffsetPart(offset); String offsetPart = InfluxV8Utils.buildOffsetPart(offset);
String query = buildQueryForFind(tenantId, timePart, alarmsPart, offsetPart); String query = buildQueryForFind(tenantId, timePart, alarmsPart, offsetPart);
logger.debug("AlarmStateHistory query for influxdb '{}'", query); 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) { 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 { 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 " 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", + "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") @SuppressWarnings("unchecked")
private List<AlarmStateHistory> queryInfluxDBForAlarmStateHistory(String query) { private List<AlarmStateHistory> queryInfluxDBForAlarmStateHistory(String query) {
@ -176,7 +131,7 @@ public class AlarmStateHistoryInfluxDbRepositoryImpl implements AlarmStateHistor
try { try {
result = this.influxDB.Query(this.config.influxDB.getName(), query, TimeUnit.MILLISECONDS); result = this.influxDB.Query(this.config.influxDB.getName(), query, TimeUnit.MILLISECONDS);
} catch (Exception e) { } 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<>(); return new LinkedList<>();
} else { } else {
logger.error("Failed to get data from InfluxDB", e); 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 com.google.inject.Inject;
import monasca.api.MonApiConfiguration; import monasca.api.ApiConfig;
import monasca.api.domain.model.measurement.MeasurementRepository; import monasca.api.domain.model.measurement.MeasurementRepo;
import monasca.api.domain.model.measurement.Measurements; import monasca.api.domain.model.measurement.Measurements;
import org.influxdb.InfluxDB; import org.influxdb.InfluxDB;
@ -27,7 +27,6 @@ import org.joda.time.format.ISODateTimeFormat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -35,21 +34,21 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable; 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 private static final Logger logger = LoggerFactory
.getLogger(MeasurementInfluxDbRepositoryImpl.class); .getLogger(InfluxV8MeasurementRepo.class);
private final MonApiConfiguration config; private final ApiConfig config;
private final InfluxDB influxDB; private final InfluxDB influxDB;
public static final DateTimeFormatter DATETIME_FORMATTER = ISODateTimeFormat.dateTimeNoMillis() public static final DateTimeFormatter DATETIME_FORMATTER = ISODateTimeFormat.dateTimeNoMillis()
.withZoneUTC(); .withZoneUTC();
@Inject @Inject
public MeasurementInfluxDbRepositoryImpl(MonApiConfiguration config, InfluxDB influxDB) { public InfluxV8MeasurementRepo(ApiConfig config, InfluxDB influxDB) {
this.config = config; this.config = config;
this.influxDB = influxDB; this.influxDB = influxDB;
@ -63,9 +62,9 @@ public class MeasurementInfluxDbRepositoryImpl implements MeasurementRepository
String serieNameRegex = buildSerieNameRegex(tenantId, config.region, name, dimensions); 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 query =
String.format("select value " + "from /%1$s/ where 1 = 1 " + " %2$s %3$s", String.format("select value " + "from /%1$s/ where 1 = 1 " + " %2$s %3$s",
@ -76,7 +75,7 @@ public class MeasurementInfluxDbRepositoryImpl implements MeasurementRepository
try { try {
result = this.influxDB.Query(this.config.influxDB.getName(), query, TimeUnit.MILLISECONDS); result = this.influxDB.Query(this.config.influxDB.getName(), query, TimeUnit.MILLISECONDS);
} catch (RuntimeException e) { } 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<>(); return new LinkedList<>();
} else { } else {
logger.error("Failed to get data from InfluxDB", e); logger.error("Failed to get data from InfluxDB", e);
@ -92,10 +91,10 @@ public class MeasurementInfluxDbRepositoryImpl implements MeasurementRepository
for (Serie serie : result) { for (Serie serie : result) {
Utils.SerieNameDecoder serieNameDecoder; InfluxV8Utils.SerieNameDecoder serieNameDecoder;
try { try {
serieNameDecoder = new Utils.SerieNameDecoder(serie.getName()); serieNameDecoder = new InfluxV8Utils.SerieNameDecoder(serie.getName());
} catch (Utils.SerieNameDecodeException e) { } catch (InfluxV8Utils.SerieNameDecodeException e) {
logger.warn("Dropping series name that is not decodable: {}", serie.getName(), e); logger.warn("Dropping series name that is not decodable: {}", serie.getName(), e);
continue; continue;
} }

View File

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

View File

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

View File

@ -14,25 +14,36 @@
package monasca.api.infrastructure.persistence.influxdb; package monasca.api.infrastructure.persistence.influxdb;
import org.joda.time.DateTime; 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.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import monasca.api.domain.model.common.Paged; 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. // Serie names match this pattern.
private static final Pattern serieNamePattern = Pattern.compile("^.+\\?.+&.+(&.+=.+)*$"); private static final Pattern serieNamePattern = Pattern.compile("^.+\\?.+&.+(&.+=.+)*$");
static final String COULD_NOT_LOOK_UP_COLUMNS_EXC_MSG = "Couldn't look up columns"; 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 SQLSanitizer() {
} }
private static final Pattern sqlUnsafePattern = Pattern.compile("^.*('|;)+.*$"); private static final Pattern sqlUnsafePattern = Pattern.compile("^.*('|;|\")+.*$");
static String sanitize(final String taintedString) throws Exception { static String sanitize(final String taintedString) throws Exception {
Matcher m = sqlUnsafePattern.matcher(taintedString); Matcher m = sqlUnsafePattern.matcher(taintedString);
if (m.matches()) { if (m.matches()) {
throw new Exception(String.format("Input from user contains single quote ['] or " + 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; 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.common.model.metric.MetricDefinition;
import monasca.api.domain.exception.EntityNotFoundException; import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition; 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.DimensionQueries;
import monasca.api.infrastructure.persistence.SubAlarmDefinitionQueries; import monasca.api.infrastructure.persistence.SubAlarmDefinitionQueries;
@ -51,7 +51,7 @@ import com.google.common.collect.Lists;
/** /**
* Alarm repository implementation. * Alarm repository implementation.
*/ */
public class AlarmDefinitionMySqlRepositoryImpl implements AlarmDefinitionRepository { public class AlarmDefinitionMySqlRepoImpl implements AlarmDefinitionRepo {
private static final Joiner COMMA_JOINER = Joiner.on(','); private static final Joiner COMMA_JOINER = Joiner.on(',');
private static final String SUB_ALARM_SQL = private static final String SUB_ALARM_SQL =
"select sa.*, sad.dimensions from sub_alarm_definition as sa " "select sa.*, sad.dimensions from sub_alarm_definition as sa "
@ -61,7 +61,7 @@ public class AlarmDefinitionMySqlRepositoryImpl implements AlarmDefinitionReposi
private final DBI db; private final DBI db;
@Inject @Inject
public AlarmDefinitionMySqlRepositoryImpl(@Named("mysql") DBI db) { public AlarmDefinitionMySqlRepoImpl(@Named("mysql") DBI db) {
this.db = 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.exception.EntityNotFoundException;
import monasca.api.domain.model.alarm.Alarm; 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.domain.model.common.Paged;
import monasca.api.infrastructure.persistence.DimensionQueries; import monasca.api.infrastructure.persistence.DimensionQueries;
import monasca.common.model.alarm.AlarmState; import monasca.common.model.alarm.AlarmState;
@ -41,8 +41,8 @@ import javax.inject.Named;
/** /**
* Alarmed metric repository implementation. * Alarmed metric repository implementation.
*/ */
public class AlarmMySqlRepositoryImpl implements AlarmRepository { public class AlarmMySqlRepoImpl implements AlarmRepo {
private static final Logger logger = LoggerFactory.getLogger(AlarmMySqlRepositoryImpl.class); private static final Logger logger = LoggerFactory.getLogger(AlarmMySqlRepoImpl.class);
private final DBI db; private final DBI db;
private static final String ALARM_SQL = 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"; + "where ad.tenant_id = :tenantId and ad.deleted_at is null %s order by a.id %s";
@Inject @Inject
public AlarmMySqlRepositoryImpl(@Named("mysql") DBI db) { public AlarmMySqlRepoImpl(@Named("mysql") DBI db) {
this.db = 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.exception.EntityNotFoundException;
import monasca.api.domain.model.common.Paged; import monasca.api.domain.model.common.Paged;
import monasca.api.domain.model.notificationmethod.NotificationMethod; 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.domain.model.notificationmethod.NotificationMethodType;
import monasca.common.persistence.BeanMapper; import monasca.common.persistence.BeanMapper;
/** /**
* Notification method repository implementation. * Notification method repository implementation.
*/ */
public class NotificationMethodMySqlRepositoryImpl implements NotificationMethodRepository { public class NotificationMethodMySqlRepoImpl implements NotificationMethodRepo {
private static final Logger LOG = LoggerFactory private static final Logger LOG = LoggerFactory
.getLogger(NotificationMethodMySqlRepositoryImpl.class); .getLogger(NotificationMethodMySqlRepoImpl.class);
private final DBI db; private final DBI db;
@Inject @Inject
public NotificationMethodMySqlRepositoryImpl(@Named("mysql") DBI db) { public NotificationMethodMySqlRepoImpl(@Named("mysql") DBI db) {
this.db = db; this.db = db;
} }

View File

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

View File

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

View File

@ -27,13 +27,13 @@ import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.Query; import org.skife.jdbi.v2.Query;
import monasca.common.model.metric.MetricDefinition; 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; import monasca.api.infrastructure.persistence.DimensionQueries;
/** /**
* Vertica metric definition repository implementation. * Vertica metric definition repository implementation.
*/ */
public class MetricDefinitionVerticaRepositoryImpl implements MetricDefinitionRepository { public class MetricDefinitionVerticaRepoImpl implements MetricDefinitionRepo {
private static final String FIND_BY_METRIC_DEF_SQL = private static final String FIND_BY_METRIC_DEF_SQL =
"select dd.id, def.name, d.name as dname, d.value as dvalue " "select dd.id, def.name, d.name as dname, d.value as dvalue "
+ "from MonMetrics.Definitions def, MonMetrics.DefinitionDimensions dd " + "from MonMetrics.Definitions def, MonMetrics.DefinitionDimensions dd "
@ -43,7 +43,7 @@ public class MetricDefinitionVerticaRepositoryImpl implements MetricDefinitionRe
private final DBI db; private final DBI db;
@Inject @Inject
public MetricDefinitionVerticaRepositoryImpl(@Named("vertica") DBI db) { public MetricDefinitionVerticaRepoImpl(@Named("vertica") DBI db) {
this.db = 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.Handle;
import org.skife.jdbi.v2.Query; 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.domain.model.statistic.Statistics;
import monasca.api.infrastructure.persistence.DimensionQueries; import monasca.api.infrastructure.persistence.DimensionQueries;
/** /**
* Vertica statistic repository implementation. * Vertica statistic repository implementation.
*/ */
public class StatisticVerticaRepositoryImpl implements StatisticRepository { public class StatisticVerticaRepoImpl implements StatisticRepo {
public static final DateTimeFormatter DATETIME_FORMATTER = ISODateTimeFormat.dateTimeNoMillis() public static final DateTimeFormatter DATETIME_FORMATTER = ISODateTimeFormat.dateTimeNoMillis()
.withZoneUTC(); .withZoneUTC();
private static final String FIND_BY_METRIC_DEF_SQL = private static final String FIND_BY_METRIC_DEF_SQL =
@ -50,7 +50,7 @@ public class StatisticVerticaRepositoryImpl implements StatisticRepository {
private final DBI db; private final DBI db;
@Inject @Inject
public StatisticVerticaRepositoryImpl(@Named("vertica") DBI db) { public StatisticVerticaRepoImpl(@Named("vertica") DBI db) {
this.db = 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.AlarmValidation;
import monasca.api.app.validation.Validation; import monasca.api.app.validation.Validation;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition; 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.api.resource.annotation.PATCH;
import monasca.common.model.alarm.AlarmExpression; import monasca.common.model.alarm.AlarmExpression;
@ -57,12 +57,12 @@ import monasca.common.model.alarm.AlarmExpression;
@Path(AlarmDefinitionResource.ALARM_DEFINITIONS_PATH) @Path(AlarmDefinitionResource.ALARM_DEFINITIONS_PATH)
public class AlarmDefinitionResource { public class AlarmDefinitionResource {
private final AlarmDefinitionService service; 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 = "alarm-definitions";
public final static String ALARM_DEFINITIONS_PATH = "/v2.0/" + ALARM_DEFINITIONS; public final static String ALARM_DEFINITIONS_PATH = "/v2.0/" + ALARM_DEFINITIONS;
@Inject @Inject
public AlarmDefinitionResource(AlarmDefinitionService service, AlarmDefinitionRepository repo) { public AlarmDefinitionResource(AlarmDefinitionService service, AlarmDefinitionRepo repo) {
this.service = service; this.service = service;
this.repo = repo; this.repo = repo;
} }

View File

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

View File

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

View File

@ -35,7 +35,7 @@ import javax.ws.rs.core.UriInfo;
import monasca.api.app.validation.Validation; import monasca.api.app.validation.Validation;
import monasca.api.domain.model.common.Paged; 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; import monasca.api.domain.model.measurement.Measurements;
/** /**
@ -44,10 +44,10 @@ import monasca.api.domain.model.measurement.Measurements;
@Path("/v2.0/metrics/measurements") @Path("/v2.0/metrics/measurements")
public class MeasurementResource { public class MeasurementResource {
private final MeasurementRepository repo; private final MeasurementRepo repo;
@Inject @Inject
public MeasurementResource(MeasurementRepository repo) { public MeasurementResource(MeasurementRepo repo) {
this.repo = 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.MetricService;
import monasca.api.app.command.CreateMetricCommand; import monasca.api.app.command.CreateMetricCommand;
import monasca.api.app.validation.Validation; 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.api.resource.exception.Exceptions;
import monasca.common.model.Services; import monasca.common.model.Services;
import monasca.common.model.metric.Metric; import monasca.common.model.metric.Metric;
import monasca.common.model.metric.MetricDefinition;
/** /**
* Metric resource implementation. * Metric resource implementation.
@ -53,10 +52,10 @@ public class MetricResource {
private static final Splitter COMMA_SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults(); private static final Splitter COMMA_SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults();
private final MetricService service; private final MetricService service;
private final MetricDefinitionRepository metricRepo; private final MetricDefinitionRepo metricRepo;
@Inject @Inject
public MetricResource(MetricService service, MetricDefinitionRepository metricRepo) { public MetricResource(MetricService service, MetricDefinitionRepo metricRepo) {
this.service = service; this.service = service;
this.metricRepo = metricRepo; this.metricRepo = metricRepo;
} }

View File

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

View File

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

View File

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

View File

@ -30,14 +30,20 @@ mysql:
checkConnectionOnBorrow: true checkConnectionOnBorrow: true
databaseConfiguration: databaseConfiguration:
# vertica | influxdb # databaseType can be (vertica | influxdb)
databaseType: influxdb databaseType: influxdb
# Uncomment if databaseType is influxDB # Uncomment if databaseType is influxDB
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 name: mon
replicationFactor: 1 replicationFactor: 1
url: http://192.168.10.4:8086 url: http://192.168.10.4:8086
# url: http://10.10.10.2:8086
user: mon_api user: mon_api
password: password password: password
@ -84,7 +90,7 @@ server:
logging: logging:
# The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL. # The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL.
level: INFO level: debug
# Logger-specific levels. # Logger-specific levels.
loggers: loggers:

View File

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

View File

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

View File

@ -25,26 +25,26 @@ import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@Test @Test
public class UtilsTest { public class InfluxV8UtilsTest {
public void SQLSanitizerSanitizeGoodDataTest() throws Exception { public void SQLSanitizerSanitizeGoodDataTest() throws Exception {
String goodString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "-_" + String goodString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "-_" +
".?/%=&鱼鸟"; ".?/%=&鱼鸟";
assert (goodString.equals(Utils.SQLSanitizer.sanitize(goodString))); assert (goodString.equals(InfluxV8Utils.SQLSanitizer.sanitize(goodString)));
} }
@Test(expectedExceptions = {Exception.class}) @Test(expectedExceptions = {Exception.class})
public void SQLSanitizerSanitizeBadDataTest1() throws Exception { public void SQLSanitizerSanitizeBadDataTest1() throws Exception {
String badStringWithSemicolon = "abcdefghijklmnopqrs;tuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "-_."; String badStringWithSemicolon = "abcdefghijklmnopqrs;tuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "-_.";
assert (badStringWithSemicolon.equals(Utils.SQLSanitizer.sanitize(badStringWithSemicolon))); assert (badStringWithSemicolon.equals(InfluxV8Utils.SQLSanitizer.sanitize(badStringWithSemicolon)));
} }
@Test(expectedExceptions = {Exception.class}) @Test(expectedExceptions = {Exception.class})
public void SQLSanitizerSanitizeBadDataTest2() throws Exception { public void SQLSanitizerSanitizeBadDataTest2() throws Exception {
String badStringWithSingleQuote = "'a'bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "-_."; String badStringWithSingleQuote = "'a'bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + "-_.";
assert (badStringWithSingleQuote.equals(Utils.SQLSanitizer.sanitize(badStringWithSingleQuote))); assert (badStringWithSingleQuote.equals(InfluxV8Utils.SQLSanitizer.sanitize(badStringWithSingleQuote)));
} }
public void whereClauseBuilderBuildTimePartTest() { public void whereClauseBuilderBuildTimePartTest() {
@ -52,7 +52,7 @@ public class UtilsTest {
DateTime startTime = new DateTime(2014, 01, 01, 01, 01, 01, DateTimeZone.UTC); DateTime startTime = new DateTime(2014, 01, 01, 01, 01, 01, DateTimeZone.UTC);
DateTime endTime = new DateTime(2014, 01, 01, 01, 01, 02, 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 { 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 // 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 // should give a good idea of the likelihood of success
checkRegex(Utils.buildSerieNameRegex(tenantId, region, "cpu.idle_perc", null), seriesNoDims, true); checkRegex(InfluxV8Utils.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), seriesWithDims, true);
// There was a bug where it was effectively doing a "startsWith" instead of pure match so test that // 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(InfluxV8Utils.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), seriesWithDims, false);
// Make sure it works with the dimension to find in the front, middle and end of the dimensions // 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 // and that it does an exact match
@ -81,10 +81,10 @@ public class UtilsTest {
String name, String goodValue, String badValue) throws Exception { String name, String goodValue, String badValue) throws Exception {
final Map<String, String> dimensions = new HashMap<String, String>(); final Map<String, String> dimensions = new HashMap<String, String>();
dimensions.put(name, goodValue); 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); 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) { 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.common.model.metric.MetricDefinition;
import monasca.api.domain.exception.EntityNotFoundException; import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.alarmdefinition.AlarmDefinition; import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepository; import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
@Test(groups = "database") @Test(groups = "database")
public class AlarmDefinitionMySqlRepositoryImplTest { public class AlarmDefinitionMySqlRepositoryImplTest {
private DBI db; private DBI db;
private Handle handle; private Handle handle;
private AlarmDefinitionRepository repo; private AlarmDefinitionRepo repo;
private List<String> alarmActions; private List<String> alarmActions;
private AlarmDefinition alarmDef_123; private AlarmDefinition alarmDef_123;
private AlarmDefinition alarmDef_234; private AlarmDefinition alarmDef_234;
@ -62,7 +62,7 @@ public class AlarmDefinitionMySqlRepositoryImplTest {
handle = db.open(); handle = db.open();
handle handle
.execute(Resources.toString(getClass().getResource("alarm.sql"), Charset.defaultCharset())); .execute(Resources.toString(getClass().getResource("alarm.sql"), Charset.defaultCharset()));
repo = new AlarmDefinitionMySqlRepositoryImpl(db); repo = new AlarmDefinitionMySqlRepoImpl(db);
alarmActions = new ArrayList<String>(); alarmActions = new ArrayList<String>();
alarmActions.add("29387234"); alarmActions.add("29387234");
@ -154,7 +154,7 @@ public class AlarmDefinitionMySqlRepositoryImplTest {
// Warning, this will truncate your mini-mon database // Warning, this will truncate your mini-mon database
db = new DBI("jdbc:mysql://192.168.10.4/mon", "monapi", "password"); db = new DBI("jdbc:mysql://192.168.10.4/mon", "monapi", "password");
handle = db.open(); handle = db.open();
repo = new AlarmDefinitionMySqlRepositoryImpl(db); repo = new AlarmDefinitionMySqlRepoImpl(db);
beforeMethod(); beforeMethod();
List<String> oldSubAlarmIds = Arrays.asList("222"); List<String> oldSubAlarmIds = Arrays.asList("222");
@ -198,7 +198,7 @@ public class AlarmDefinitionMySqlRepositoryImplTest {
// Warning, this will truncate your mini-mon database // Warning, this will truncate your mini-mon database
db = new DBI("jdbc:mysql://192.168.10.4/mon", "monapi", "password"); db = new DBI("jdbc:mysql://192.168.10.4/mon", "monapi", "password");
handle = db.open(); handle = db.open();
repo = new AlarmDefinitionMySqlRepositoryImpl(db); repo = new AlarmDefinitionMySqlRepoImpl(db);
beforeMethod(); beforeMethod();
assertEquals( assertEquals(
@ -221,7 +221,7 @@ public class AlarmDefinitionMySqlRepositoryImplTest {
// Warning, this will truncate your mini-mon database // Warning, this will truncate your mini-mon database
db = new DBI("jdbc:mysql://192.168.10.4/mon", "monapi", "password"); db = new DBI("jdbc:mysql://192.168.10.4/mon", "monapi", "password");
handle = db.open(); handle = db.open();
repo = new AlarmDefinitionMySqlRepositoryImpl(db); repo = new AlarmDefinitionMySqlRepoImpl(db);
beforeMethod(); beforeMethod();
assertEquals( assertEquals(

View File

@ -23,7 +23,7 @@ import com.google.common.collect.ImmutableMap.Builder;
import monasca.api.domain.exception.EntityNotFoundException; import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.alarm.Alarm; 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.AlarmState;
import monasca.common.model.alarm.AlarmSubExpression; import monasca.common.model.alarm.AlarmSubExpression;
import monasca.common.model.metric.MetricDefinition; import monasca.common.model.metric.MetricDefinition;
@ -53,7 +53,7 @@ public class AlarmMySqlRepositoryImplTest {
private static final String ALARM_ID = "234111"; private static final String ALARM_ID = "234111";
private DBI db; private DBI db;
private Handle handle; private Handle handle;
private AlarmRepository repo; private AlarmRepo repo;
private List<String> alarmActions; private List<String> alarmActions;
private Alarm compoundAlarm; private Alarm compoundAlarm;
private Alarm alarm1; private Alarm alarm1;
@ -71,7 +71,7 @@ public class AlarmMySqlRepositoryImplTest {
handle handle
.execute(Resources.toString(getClass().getResource("alarm.sql"), Charset.defaultCharset())); .execute(Resources.toString(getClass().getResource("alarm.sql"), Charset.defaultCharset()));
*/ */
repo = new AlarmMySqlRepositoryImpl(db); repo = new AlarmMySqlRepoImpl(db);
alarmActions = new ArrayList<String>(); alarmActions = new ArrayList<String>();
alarmActions.add("29387234"); 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.exception.EntityNotFoundException;
import monasca.api.domain.model.notificationmethod.NotificationMethod; import monasca.api.domain.model.notificationmethod.NotificationMethod;
import monasca.api.domain.model.notificationmethod.NotificationMethodType; import monasca.api.domain.model.notificationmethod.NotificationMethodType;
import monasca.api.infrastructure.persistence.mysql.NotificationMethodMySqlRepositoryImpl;
@Test @Test
public class NotificationMethodMySqlRepositoryImplTest { public class NotificationMethodMySqlRepositoryImplTest {
private DBI db; private DBI db;
private Handle handle; private Handle handle;
private NotificationMethodMySqlRepositoryImpl repo; private NotificationMethodMySqlRepoImpl repo;
@BeforeClass @BeforeClass
protected void beforeClass() throws Exception { protected void beforeClass() throws Exception {
@ -48,7 +47,7 @@ public class NotificationMethodMySqlRepositoryImplTest {
handle = db.open(); handle = db.open();
handle.execute(Resources.toString(getClass().getResource("notification_method.sql"), handle.execute(Resources.toString(getClass().getResource("notification_method.sql"),
Charset.defaultCharset())); Charset.defaultCharset()));
repo = new NotificationMethodMySqlRepositoryImpl(db); repo = new NotificationMethodMySqlRepoImpl(db);
} }
@AfterClass @AfterClass

View File

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

View File

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

View File

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

View File

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

View File

@ -34,11 +34,11 @@ import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Key; import com.google.inject.Key;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
import monasca.api.MonApiConfiguration; import monasca.api.ApiConfig;
import monasca.api.MonApiModule; import monasca.api.MonApiModule;
import monasca.api.app.MetricService; import monasca.api.app.MetricService;
import monasca.api.app.command.CreateMetricCommand; 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.AbstractMonApiResourceTest;
import monasca.api.resource.MetricResource; import monasca.api.resource.MetricResource;
import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.ClientResponse;
@ -49,8 +49,8 @@ public class MetricIntegrationTest extends AbstractMonApiResourceTest {
private DBI db; private DBI db;
private MetricService service; private MetricService service;
private Producer<String, String> producer; private Producer<String, String> producer;
private MonApiConfiguration config; private ApiConfig config;
private MetricDefinitionRepository metricRepo; private MetricDefinitionRepo metricRepo;
private Map<String, String> dimensions; private Map<String, String> dimensions;
@Override @Override
@ -59,14 +59,14 @@ public class MetricIntegrationTest extends AbstractMonApiResourceTest {
Handle handle = db.open(); Handle handle = db.open();
handle.execute("truncate table access"); handle.execute("truncate table access");
db.close(handle); db.close(handle);
metricRepo = mock(MetricDefinitionRepository.class); metricRepo = mock(MetricDefinitionRepo.class);
service = new MetricService(config, producer, metricRegistry); service = new MetricService(config, producer, metricRegistry);
addResources(new MetricResource(service, metricRepo)); addResources(new MetricResource(service, metricRepo));
} }
@BeforeTest @BeforeTest
protected void beforeTest() throws Exception { 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)); Injector injector = Guice.createInjector(new MonApiModule(environment, config));
producer = injector.getInstance(Key.get(new TypeLiteral<Producer<String, String>>() {})); 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.common.io.Resources;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import monasca.api.MonApiConfiguration; import monasca.api.ApiConfig;
import monasca.api.MonApiModule; import monasca.api.MonApiModule;
import monasca.api.app.command.CreateNotificationMethodCommand; import monasca.api.app.command.CreateNotificationMethodCommand;
import monasca.api.domain.exception.EntityNotFoundException; import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.notificationmethod.NotificationMethod; 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.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.AbstractMonApiResourceTest;
import monasca.api.resource.NotificationMethodResource; import monasca.api.resource.NotificationMethodResource;
import com.sun.jersey.api.client.ClientResponse; 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 static final String TENANT_ID = "notification-method-test";
private DBI db; private DBI db;
private NotificationMethod notificationMethod; private NotificationMethod notificationMethod;
private NotificationMethodRepository repo; private NotificationMethodRepo repo;
@Override @Override
protected void setupResources() throws Exception { 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())"); .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); db.close(handle);
repo = new NotificationMethodMySqlRepositoryImpl(db); repo = new NotificationMethodMySqlRepoImpl(db);
addResources(new NotificationMethodResource(repo)); addResources(new NotificationMethodResource(repo));
} }
@BeforeTest @BeforeTest
protected void beforeTest() throws Exception { 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)); Injector injector = Guice.createInjector(new MonApiModule(environment, config));
db = injector.getInstance(DBI.class); db = injector.getInstance(DBI.class);
Handle handle = db.open(); Handle handle = db.open();
handle.execute(Resources.toString( handle.execute(Resources.toString(
NotificationMethodMySqlRepositoryImpl.class.getResource("notification_method.sql"), NotificationMethodMySqlRepoImpl.class.getResource("notification_method.sql"),
Charset.defaultCharset())); Charset.defaultCharset()));
handle.close(); handle.close();

View File

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

View File

@ -34,7 +34,7 @@ import org.testng.annotations.Test;
import monasca.api.app.MetricService; import monasca.api.app.MetricService;
import monasca.api.app.command.CreateMetricCommand; 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 monasca.api.resource.exception.ErrorMessages;
import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.ClientResponse;
@ -42,7 +42,7 @@ import com.sun.jersey.api.client.ClientResponse;
public class MetricResourceTest extends AbstractMonApiResourceTest { public class MetricResourceTest extends AbstractMonApiResourceTest {
private Map<String, String> dimensions; private Map<String, String> dimensions;
private MetricService service; private MetricService service;
private MetricDefinitionRepository metricRepo; private MetricDefinitionRepo metricRepo;
long timestamp; long timestamp;
@Override @Override
@ -57,7 +57,7 @@ public class MetricResourceTest extends AbstractMonApiResourceTest {
service = mock(MetricService.class); service = mock(MetricService.class);
doNothing().when(service).create(any(List.class), anyString(), anyString()); doNothing().when(service).create(any(List.class), anyString(), anyString());
metricRepo = mock(MetricDefinitionRepository.class); metricRepo = mock(MetricDefinitionRepo.class);
addResources(new MetricResource(service, metricRepo)); 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.app.command.CreateNotificationMethodCommand;
import monasca.api.domain.exception.EntityNotFoundException; import monasca.api.domain.exception.EntityNotFoundException;
import monasca.api.domain.model.notificationmethod.NotificationMethod; 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.domain.model.notificationmethod.NotificationMethodType;
import monasca.api.resource.exception.ErrorMessages; import monasca.api.resource.exception.ErrorMessages;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -37,7 +37,7 @@ import static org.testng.Assert.*;
@Test @Test
public class NotificationMethodResourceTest extends AbstractMonApiResourceTest { public class NotificationMethodResourceTest extends AbstractMonApiResourceTest {
private NotificationMethod notificationMethod, notificationMethodWebhook, notificationMethodPagerduty; private NotificationMethod notificationMethod, notificationMethodWebhook, notificationMethodPagerduty;
private NotificationMethodRepository repo; private NotificationMethodRepo repo;
@Override @Override
protected void setupResources() throws Exception { protected void setupResources() throws Exception {
@ -49,7 +49,7 @@ public class NotificationMethodResourceTest extends AbstractMonApiResourceTest {
notificationMethodPagerduty = notificationMethodPagerduty =
new NotificationMethod("12345", "MyPd", NotificationMethodType.PAGERDUTY, "nzH2LVRdMzun11HNC2oD"); 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())) when(repo.create(eq("abc"), eq("MyEmail"), eq(NotificationMethodType.EMAIL), anyString()))
.thenReturn(notificationMethod); .thenReturn(notificationMethod);
when(repo.create(eq("abc"), eq("MyWh"), eq(NotificationMethodType.WEBHOOK), anyString())) 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.joda.time.DateTime;
import org.testng.annotations.Test; 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; import com.sun.jersey.api.client.ClientResponse;
@Test @Test
public class StatisticResourceTest extends AbstractMonApiResourceTest { public class StatisticResourceTest extends AbstractMonApiResourceTest {
private StatisticRepository statisticRepo; private StatisticRepo statisticRepo;
long timestamp; long timestamp;
@Override @Override
protected void setupResources() throws Exception { protected void setupResources() throws Exception {
super.setupResources(); super.setupResources();
statisticRepo = mock(StatisticRepository.class); statisticRepo = mock(StatisticRepo.class);
addResources(new StatisticResource(statisticRepo)); 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.common.Link;
import monasca.api.domain.model.version.Version; import monasca.api.domain.model.version.Version;
import monasca.api.domain.model.version.Version.VersionStatus; 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; import com.sun.jersey.api.client.GenericType;
@Test @Test
public class VersionResourceTest extends AbstractMonApiResourceTest { public class VersionResourceTest extends AbstractMonApiResourceTest {
private Version version; private Version version;
private VersionRepository repo; private VersionRepo repo;
@Override @Override
protected void setupResources() throws Exception { protected void setupResources() throws Exception {
@ -49,7 +49,7 @@ public class VersionResourceTest extends AbstractMonApiResourceTest {
version.setLinks(Arrays.asList(new Link("self", version.setLinks(Arrays.asList(new Link("self",
"https://cloudsvc.example.com/v2.0"))); "https://cloudsvc.example.com/v2.0")));
repo = mock(VersionRepository.class); repo = mock(VersionRepo.class);
when(repo.findById(eq("v2.0"))).thenReturn(version); when(repo.findById(eq("v2.0"))).thenReturn(version);
when(repo.find()).thenReturn(Arrays.asList(version)); when(repo.find()).thenReturn(Arrays.asList(version));
addResources(new VersionResource(repo)); addResources(new VersionResource(repo));