monasca-api/java/src/main/java/monasca/api/infrastructure/persistence/influxdb/InfluxV9DimensionRepo.java

194 lines
6.3 KiB
Java

/*
* (C) Copyright 2016 Hewlett Packard Enterprise Development LP
*
* 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.google.common.base.Strings;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.Set;
import monasca.api.ApiConfig;
import monasca.api.domain.model.dimension.DimensionName;
import monasca.api.domain.model.dimension.DimensionValue;
import monasca.api.domain.model.dimension.DimensionRepo;
public class InfluxV9DimensionRepo implements DimensionRepo {
private static final Logger logger = LoggerFactory.getLogger(InfluxV9DimensionRepo.class);
private final ApiConfig config;
private final InfluxV9RepoReader influxV9RepoReader;
private final InfluxV9Utils influxV9Utils;
private final String region;
private final ObjectMapper objectMapper = new ObjectMapper();
@Inject
public InfluxV9DimensionRepo(ApiConfig config,
InfluxV9RepoReader influxV9RepoReader,
InfluxV9Utils influxV9Utils) {
this.config = config;
this.region = config.region;
this.influxV9RepoReader = influxV9RepoReader;
this.influxV9Utils = influxV9Utils;
}
@Override
public List<DimensionValue> findValues(
String metricName,
String tenantId,
String dimensionName,
String offset,
int limit) throws Exception
{
//
// Use treeset to keep list in alphabetic/predictable order
// for string based offset.
//
List<DimensionValue> dimensionValueList = new ArrayList<>();
Set<String> matchingValues = new TreeSet<String>();
String dimNamePart = "and \""
+ this.influxV9Utils.sanitize(dimensionName)
+ "\" =~ /.*/";
String q = String.format("show series %1$s where %2$s %3$s",
this.influxV9Utils.namePart(metricName, false),
this.influxV9Utils.privateTenantIdPart(tenantId),
dimNamePart);
logger.debug("Dimension values query: {}", q);
String r = this.influxV9RepoReader.read(q);
Series series = this.objectMapper.readValue(r, Series.class);
if (!series.isEmpty()) {
for (Serie serie : series.getSeries()) {
for (String[] values : serie.getValues()) {
Map<String, String> dimensions = this.influxV9Utils.getDimensions(values, serie.getColumns());
for (Map.Entry<String, String> entry : dimensions.entrySet()) {
if (dimensionName.equals(entry.getKey())) {
matchingValues.add(entry.getValue());
}
}
}
}
}
List<String> filteredValues = filterDimensionValues(matchingValues,
limit,
offset);
for (String filteredValue : filteredValues) {
DimensionValue dimValue = new DimensionValue(metricName, dimensionName, filteredValue);
dimensionValueList.add(dimValue);
}
return dimensionValueList;
}
private List<String> filterDimensionValues(Set<String> matchingValues,
int limit,
String offset)
{
Boolean haveOffset = !Strings.isNullOrEmpty(offset);
List<String> filteredValues = new ArrayList<String>();
int remaining_limit = limit + 1;
for (String dimVal : matchingValues) {
if (remaining_limit <= 0) {
break;
}
if (haveOffset && dimVal.compareTo(offset) <= 0) {
continue;
}
filteredValues.add(dimVal);
remaining_limit--;
}
return filteredValues;
}
@Override
public List<DimensionName> findNames(
String metricName,
String tenantId,
String offset,
int limit) throws Exception
{
//
// Use treeset to keep list in alphabetic/predictable order
// for string based offset.
//
List<DimensionName> dimensionNameList = new ArrayList<>();
Set<String> matchingNames = new TreeSet<String>();
String q = String.format("show series %1$s where %2$s",
this.influxV9Utils.namePart(metricName, false),
this.influxV9Utils.privateTenantIdPart(tenantId));
logger.debug("Dimension names query: {}", q);
String r = this.influxV9RepoReader.read(q);
Series series = this.objectMapper.readValue(r, Series.class);
if (!series.isEmpty()) {
for (Serie serie : series.getSeries()) {
for (String[] names : serie.getValues()) {
Map<String, String> dimensions = this.influxV9Utils.getDimensions(names, serie.getColumns());
for (Map.Entry<String, String> entry : dimensions.entrySet()) {
matchingNames.add(entry.getKey());
}
}
}
}
List<String> filteredNames = filterDimensionNames(matchingNames, limit, offset);
for (String filteredName : filteredNames) {
DimensionName dimName = new DimensionName(metricName, filteredName);
dimensionNameList.add(dimName);
}
return dimensionNameList;
}
private List<String> filterDimensionNames(Set<String> matchingNames,
int limit,
String offset) {
Boolean haveOffset = !Strings.isNullOrEmpty(offset);
List<String> filteredNames = new ArrayList<String>();
int remaining_limit = limit + 1;
for (String dimName : matchingNames) {
if (remaining_limit <= 0) {
break;
}
if (haveOffset && dimName.compareTo(offset) <= 0) {
continue;
}
filteredNames.add(dimName);
remaining_limit--;
}
return filteredNames;
}
}