Persistence alias support (#18286)
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>pull/18302/head
parent
d7abc08cfd
commit
32b0a40252
|
@ -449,7 +449,7 @@ public abstract class AbstractDynamoDBItem<T> implements DynamoDBItem<T> {
|
|||
if (deserializedState == null) {
|
||||
return null;
|
||||
}
|
||||
return new DynamoDBHistoricItem(getName(), deserializedState, getTime().toInstant());
|
||||
return new DynamoDBHistoricItem(item.getName(), deserializedState, getTime().toInstant());
|
||||
} catch (Exception e) {
|
||||
logger.trace("Failed to convert state '{}' to item {} {}: {} {}. Data persisted with incompatible item.",
|
||||
this.state, item.getClass().getSimpleName(), item.getName(), e.getClass().getSimpleName(),
|
||||
|
|
|
@ -350,6 +350,11 @@ public class DynamoDBPersistenceService implements QueryablePersistenceService {
|
|||
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter) {
|
||||
return query(filter, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter, @Nullable String alias) {
|
||||
logIfManyQueuedTasks();
|
||||
Instant start = Instant.now();
|
||||
String filterDescription = filterToString(filter);
|
||||
|
@ -419,7 +424,7 @@ public class DynamoDBPersistenceService implements QueryablePersistenceService {
|
|||
item.getClass().getSimpleName(), dtoClass.getSimpleName(), tableName);
|
||||
|
||||
QueryEnhancedRequest queryExpression = DynamoDBQueryUtils.createQueryExpression(dtoClass,
|
||||
localTableNameResolver.getTableSchema(), item, filter, unitProvider);
|
||||
localTableNameResolver.getTableSchema(), item, alias, filter, unitProvider);
|
||||
|
||||
CompletableFuture<List<DynamoDBItem<?>>> itemsFuture = new CompletableFuture<>();
|
||||
final SdkPublisher<? extends DynamoDBItem<?>> itemPublisher = table.query(queryExpression).items();
|
||||
|
|
|
@ -44,19 +44,21 @@ public class DynamoDBQueryUtils {
|
|||
* @param dtoClass dto class
|
||||
* @param expectedTableSchema table schema to query against
|
||||
* @param item item corresponding to filter
|
||||
* @param alias corresponding to item
|
||||
* @param filter filter for the query
|
||||
* @return DynamoDBQueryExpression corresponding to the given FilterCriteria
|
||||
* @param unitProvider the unit provider for number with dimension
|
||||
* @throws IllegalArgumentException when schema is not fully resolved
|
||||
*/
|
||||
public static QueryEnhancedRequest createQueryExpression(Class<? extends DynamoDBItem<?>> dtoClass,
|
||||
ExpectedTableSchema expectedTableSchema, Item item, FilterCriteria filter, UnitProvider unitProvider) {
|
||||
ExpectedTableSchema expectedTableSchema, Item item, @Nullable String alias, FilterCriteria filter,
|
||||
UnitProvider unitProvider) {
|
||||
if (!expectedTableSchema.isFullyResolved()) {
|
||||
throw new IllegalArgumentException("Schema not resolved");
|
||||
}
|
||||
QueryEnhancedRequest.Builder queryBuilder = QueryEnhancedRequest.builder()
|
||||
.scanIndexForward(filter.getOrdering() == Ordering.ASCENDING);
|
||||
String itemName = filter.getItemName();
|
||||
String itemName = alias != null ? alias : filter.getItemName();
|
||||
if (itemName == null) {
|
||||
throw new IllegalArgumentException("Item name not set");
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ public class InfluxDBPersistenceService implements ModifiablePersistenceService
|
|||
logger.warn("InfluxDB service not ready. Storing {} rejected.", item);
|
||||
return;
|
||||
}
|
||||
convert(item, state, date.toInstant(), null).thenAccept(point -> {
|
||||
convert(item, state, date.toInstant(), alias).thenAccept(point -> {
|
||||
if (point == null) {
|
||||
logger.trace("Ignoring item {}, conversion to an InfluxDB point failed.", item.getName());
|
||||
return;
|
||||
|
@ -233,27 +233,33 @@ public class InfluxDBPersistenceService implements ModifiablePersistenceService
|
|||
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter) {
|
||||
return query(filter, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter, @Nullable String alias) {
|
||||
String itemName = filter.getItemName();
|
||||
if (itemName == null) {
|
||||
logger.warn("Item name is missing in filter {} when querying data.", filter);
|
||||
return List.of();
|
||||
}
|
||||
if (serviceActivated && checkConnection()) {
|
||||
logger.trace(
|
||||
"Query-Filter: itemname: {}, ordering: {}, state: {}, operator: {}, getBeginDate: {}, getEndDate: {}, getPageSize: {}, getPageNumber: {}",
|
||||
filter.getItemName(), filter.getOrdering().toString(), filter.getState(), filter.getOperator(),
|
||||
itemName, filter.getOrdering().toString(), filter.getState(), filter.getOperator(),
|
||||
filter.getBeginDate(), filter.getEndDate(), filter.getPageSize(), filter.getPageNumber());
|
||||
if (filter.getItemName() == null) {
|
||||
logger.warn("Item name is missing in filter {} when querying data.", filter);
|
||||
return List.of();
|
||||
}
|
||||
|
||||
List<InfluxDBRepository.InfluxRow> results = influxDBRepository.query(filter,
|
||||
configuration.getRetentionPolicy());
|
||||
return results.stream().map(this::mapRowToHistoricItem).collect(Collectors.toList());
|
||||
configuration.getRetentionPolicy(), alias);
|
||||
return results.stream().map(r -> mapRowToHistoricItem(r, itemName)).collect(Collectors.toList());
|
||||
} else {
|
||||
logger.debug("Query for persisted data ignored, InfluxDB is not connected");
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
||||
private HistoricItem mapRowToHistoricItem(InfluxDBRepository.InfluxRow row) {
|
||||
State state = InfluxDBStateConvertUtils.objectToState(row.value(), row.itemName(), itemRegistry);
|
||||
private HistoricItem mapRowToHistoricItem(InfluxDBRepository.InfluxRow row, String itemName) {
|
||||
State state = InfluxDBStateConvertUtils.objectToState(row.value(), itemName, itemRegistry);
|
||||
return new InfluxDBHistoricItem(row.itemName(), state, row.time());
|
||||
}
|
||||
|
||||
|
@ -314,8 +320,8 @@ public class InfluxDBPersistenceService implements ModifiablePersistenceService
|
|||
}
|
||||
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
String measurementName = storeAlias != null && !storeAlias.isBlank() ? storeAlias : itemName;
|
||||
measurementName = influxDBMetadataService.getMeasurementNameOrDefault(itemName, measurementName);
|
||||
String alias = storeAlias != null && !storeAlias.isBlank() ? storeAlias : itemName;
|
||||
String measurementName = influxDBMetadataService.getMeasurementNameOrDefault(alias);
|
||||
|
||||
if (configuration.isReplaceUnderscore()) {
|
||||
measurementName = measurementName.replace('_', '.');
|
||||
|
@ -326,7 +332,7 @@ public class InfluxDBPersistenceService implements ModifiablePersistenceService
|
|||
Object value = InfluxDBStateConvertUtils.stateToObject(storeState);
|
||||
|
||||
InfluxPoint.Builder pointBuilder = InfluxPoint.newBuilder(measurementName).withTime(timeStamp)
|
||||
.withValue(value).withTag(TAG_ITEM_NAME, itemName);
|
||||
.withValue(value).withTag(TAG_ITEM_NAME, alias);
|
||||
|
||||
if (configuration.isAddCategoryTag()) {
|
||||
String categoryName = Objects.requireNonNullElse(category, "n/a");
|
||||
|
@ -342,7 +348,7 @@ public class InfluxDBPersistenceService implements ModifiablePersistenceService
|
|||
pointBuilder.withTag(TAG_LABEL_NAME, labelName);
|
||||
}
|
||||
|
||||
influxDBMetadataService.getMetaData(itemName)
|
||||
influxDBMetadataService.getMetaData(alias)
|
||||
.ifPresent(metadata -> metadata.getConfiguration().forEach(pointBuilder::withTag));
|
||||
|
||||
return pointBuilder.build();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
package org.openhab.persistence.influxdb.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.persistence.FilterCriteria;
|
||||
|
||||
/**
|
||||
|
@ -24,12 +25,13 @@ import org.openhab.core.persistence.FilterCriteria;
|
|||
public interface FilterCriteriaQueryCreator {
|
||||
/**
|
||||
* Create query from {@link FilterCriteria}
|
||||
*
|
||||
*
|
||||
* @param criteria Criteria to create query from
|
||||
* @param retentionPolicy Name of the retentionPolicy/bucket to use in query
|
||||
* @param alias
|
||||
* @return Created query as a String
|
||||
*/
|
||||
String createQuery(FilterCriteria criteria, String retentionPolicy);
|
||||
String createQuery(FilterCriteria criteria, String retentionPolicy, @Nullable String alias);
|
||||
|
||||
default String getOperationSymbol(FilterCriteria.Operator operator, InfluxDBVersion version) {
|
||||
return switch (operator) {
|
||||
|
|
|
@ -42,10 +42,9 @@ public class InfluxDBMetadataService {
|
|||
* get the measurement name from the item metadata or return the provided default
|
||||
*
|
||||
* @param itemName the item name
|
||||
* @param defaultName the default measurement name (
|
||||
* @return the metadata measurement name if present, defaultName otherwise
|
||||
*/
|
||||
public String getMeasurementNameOrDefault(String itemName, String defaultName) {
|
||||
public String getMeasurementNameOrDefault(String itemName) {
|
||||
Optional<Metadata> metadata = getMetaData(itemName);
|
||||
if (metadata.isPresent()) {
|
||||
String metaName = metadata.get().getValue();
|
||||
|
@ -54,7 +53,7 @@ public class InfluxDBMetadataService {
|
|||
}
|
||||
}
|
||||
|
||||
return defaultName;
|
||||
return itemName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.persistence.FilterCriteria;
|
||||
|
||||
/**
|
||||
|
@ -63,10 +64,11 @@ public interface InfluxDBRepository {
|
|||
* Executes Flux query
|
||||
*
|
||||
* @param filter the query filter
|
||||
* @param alias
|
||||
* @return Query results
|
||||
*
|
||||
*
|
||||
*/
|
||||
List<InfluxRow> query(FilterCriteria filter, String retentionPolicy);
|
||||
List<InfluxRow> query(FilterCriteria filter, String retentionPolicy, @Nullable String alias);
|
||||
|
||||
/**
|
||||
* Write points to database
|
||||
|
|
|
@ -50,9 +50,10 @@ public class InfluxDB1FilterCriteriaQueryCreatorImpl implements FilterCriteriaQu
|
|||
}
|
||||
|
||||
@Override
|
||||
public String createQuery(FilterCriteria criteria, String retentionPolicy) {
|
||||
public String createQuery(FilterCriteria criteria, String retentionPolicy, @Nullable String alias) {
|
||||
final String itemName = Objects.requireNonNull(criteria.getItemName()); // we checked non-null before
|
||||
final String tableName = getTableName(itemName);
|
||||
final String localAlias = alias != null ? alias : itemName;
|
||||
final String tableName = getTableName(localAlias);
|
||||
final boolean hasCriteriaName = itemName != null;
|
||||
|
||||
Select select = select().column("\"" + COLUMN_VALUE_NAME_V1 + "\"::field")
|
||||
|
@ -61,8 +62,8 @@ public class InfluxDB1FilterCriteriaQueryCreatorImpl implements FilterCriteriaQu
|
|||
|
||||
Where where = select.where();
|
||||
|
||||
if (itemName != null && !tableName.equals(itemName)) {
|
||||
where.and(BuiltQuery.QueryBuilder.eq(TAG_ITEM_NAME, itemName));
|
||||
if (localAlias != null && !tableName.equals(localAlias)) {
|
||||
where.and(BuiltQuery.QueryBuilder.eq(TAG_ITEM_NAME, localAlias));
|
||||
}
|
||||
if (criteria.getBeginDate() != null) {
|
||||
where.and(BuiltQuery.QueryBuilder.gte(COLUMN_TIME_NAME_V1, criteria.getBeginDate().toInstant().toString()));
|
||||
|
@ -99,7 +100,7 @@ public class InfluxDB1FilterCriteriaQueryCreatorImpl implements FilterCriteriaQu
|
|||
return "/.*/";
|
||||
}
|
||||
|
||||
String name = influxDBMetadataService.getMeasurementNameOrDefault(itemName, itemName);
|
||||
String name = influxDBMetadataService.getMeasurementNameOrDefault(itemName);
|
||||
|
||||
if (configuration.isReplaceUnderscore()) {
|
||||
name = name.replace('_', '.');
|
||||
|
|
|
@ -12,10 +12,7 @@
|
|||
*/
|
||||
package org.openhab.persistence.influxdb.internal.influx1;
|
||||
|
||||
import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.COLUMN_TIME_NAME_V1;
|
||||
import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.COLUMN_VALUE_NAME_V1;
|
||||
import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.FIELD_VALUE_NAME;
|
||||
import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.TAG_ITEM_NAME;
|
||||
import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
|
@ -168,11 +165,11 @@ public class InfluxDB1RepositoryImpl implements InfluxDBRepository {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<InfluxRow> query(FilterCriteria filter, String retentionPolicy) {
|
||||
public List<InfluxRow> query(FilterCriteria filter, String retentionPolicy, @Nullable String alias) {
|
||||
try {
|
||||
final InfluxDB currentClient = client;
|
||||
if (currentClient != null) {
|
||||
String query = queryCreator.createQuery(filter, retentionPolicy);
|
||||
String query = queryCreator.createQuery(filter, retentionPolicy, alias);
|
||||
logger.trace("Query {}", query);
|
||||
Query parsedQuery = new Query(query, configuration.getDatabaseName());
|
||||
List<QueryResult.Result> results = currentClient.query(parsedQuery, TimeUnit.MILLISECONDS).getResults();
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
*/
|
||||
package org.openhab.persistence.influxdb.internal.influx2;
|
||||
|
||||
import static com.influxdb.query.dsl.functions.restriction.Restrictions.measurement;
|
||||
import static com.influxdb.query.dsl.functions.restriction.Restrictions.tag;
|
||||
import static com.influxdb.query.dsl.functions.restriction.Restrictions.*;
|
||||
import static org.openhab.persistence.influxdb.internal.InfluxDBConstants.*;
|
||||
import static org.openhab.persistence.influxdb.internal.InfluxDBStateConvertUtils.stateToObject;
|
||||
|
||||
|
@ -21,6 +20,7 @@ import java.time.temporal.ChronoUnit;
|
|||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.persistence.FilterCriteria;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.persistence.influxdb.internal.FilterCriteriaQueryCreator;
|
||||
|
@ -49,7 +49,7 @@ public class InfluxDB2FilterCriteriaQueryCreatorImpl implements FilterCriteriaQu
|
|||
}
|
||||
|
||||
@Override
|
||||
public String createQuery(FilterCriteria criteria, String retentionPolicy) {
|
||||
public String createQuery(FilterCriteria criteria, String retentionPolicy, @Nullable String alias) {
|
||||
Flux flux = Flux.from(retentionPolicy);
|
||||
|
||||
RangeFlux range = flux.range();
|
||||
|
@ -66,7 +66,8 @@ public class InfluxDB2FilterCriteriaQueryCreatorImpl implements FilterCriteriaQu
|
|||
flux = range;
|
||||
|
||||
String itemName = Objects.requireNonNull(criteria.getItemName()); // we checked non-null before
|
||||
String name = influxDBMetadataService.getMeasurementNameOrDefault(itemName, itemName);
|
||||
final String localAlias = alias != null ? alias : itemName;
|
||||
String name = influxDBMetadataService.getMeasurementNameOrDefault(localAlias);
|
||||
String measurementName = configuration.isReplaceUnderscore() ? name.replace('_', '.') : name;
|
||||
flux = flux.filter(measurement().equal(measurementName));
|
||||
if (!measurementName.equals(itemName)) {
|
||||
|
|
|
@ -176,7 +176,7 @@ public class InfluxDB2RepositoryImpl implements InfluxDBRepository {
|
|||
String predicate = "";
|
||||
String itemName = filter.getItemName();
|
||||
if (itemName != null) {
|
||||
String name = influxDBMetadataService.getMeasurementNameOrDefault(itemName, itemName);
|
||||
String name = influxDBMetadataService.getMeasurementNameOrDefault(itemName);
|
||||
String measurementName = configuration.isReplaceUnderscore() ? name.replace('_', '.') : name;
|
||||
predicate = "(_measurement=\"" + measurementName + "\")";
|
||||
}
|
||||
|
@ -213,11 +213,11 @@ public class InfluxDB2RepositoryImpl implements InfluxDBRepository {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<InfluxRow> query(FilterCriteria filter, String retentionPolicy) {
|
||||
public List<InfluxRow> query(FilterCriteria filter, String retentionPolicy, @Nullable String alias) {
|
||||
try {
|
||||
final QueryApi currentQueryAPI = queryAPI;
|
||||
if (currentQueryAPI != null) {
|
||||
String query = queryCreator.createQuery(filter, retentionPolicy);
|
||||
String query = queryCreator.createQuery(filter, retentionPolicy, alias);
|
||||
logger.trace("Query {}", query);
|
||||
List<FluxTable> clientResult = currentQueryAPI.query(query);
|
||||
return clientResult.stream().flatMap(this::mapRawResultToHistoric).toList();
|
||||
|
|
|
@ -76,11 +76,11 @@ public class InfluxFilterCriteriaQueryCreatorImplTest {
|
|||
public void testSimpleItemQueryWithoutParams() {
|
||||
FilterCriteria criteria = createBaseCriteria();
|
||||
|
||||
String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY);
|
||||
String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(queryV1,
|
||||
equalTo("SELECT \"value\"::field,\"item\"::tag FROM \"origin\".\"sampleItem\" ORDER BY time DESC;"));
|
||||
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY);
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(queryV2, equalTo("""
|
||||
from(bucket:"origin")
|
||||
\t|> range(start:-100y, stop:100y)
|
||||
|
@ -97,13 +97,13 @@ public class InfluxFilterCriteriaQueryCreatorImplTest {
|
|||
criteria.setBeginDate(now);
|
||||
criteria.setEndDate(tomorrow);
|
||||
|
||||
String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY);
|
||||
String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY, null);
|
||||
String expectedQueryV1 = String.format(
|
||||
"SELECT \"value\"::field,\"item\"::tag FROM \"origin\".\"sampleItem\" WHERE time >= '%s' AND time <= '%s' ORDER BY time DESC;",
|
||||
now.toInstant(), tomorrow.toInstant());
|
||||
assertThat(queryV1, equalTo(expectedQueryV1));
|
||||
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY);
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY, null);
|
||||
String expectedQueryV2 = String.format("""
|
||||
from(bucket:"origin")
|
||||
\t|> range(start:%s, stop:%s)
|
||||
|
@ -120,11 +120,11 @@ public class InfluxFilterCriteriaQueryCreatorImplTest {
|
|||
criteria.setOperator(FilterCriteria.Operator.LTE);
|
||||
criteria.setState(new PercentType(90));
|
||||
|
||||
String query = instanceV1.createQuery(criteria, RETENTION_POLICY);
|
||||
String query = instanceV1.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(query, equalTo(
|
||||
"SELECT \"value\"::field,\"item\"::tag FROM \"origin\".\"sampleItem\" WHERE value <= 90 ORDER BY time DESC;"));
|
||||
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY);
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(queryV2, equalTo("""
|
||||
from(bucket:"origin")
|
||||
\t|> range(start:-100y, stop:100y)
|
||||
|
@ -140,11 +140,11 @@ public class InfluxFilterCriteriaQueryCreatorImplTest {
|
|||
criteria.setPageNumber(2);
|
||||
criteria.setPageSize(10);
|
||||
|
||||
String query = instanceV1.createQuery(criteria, RETENTION_POLICY);
|
||||
String query = instanceV1.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(query, equalTo(
|
||||
"SELECT \"value\"::field,\"item\"::tag FROM \"origin\".\"sampleItem\" ORDER BY time DESC LIMIT 10 OFFSET 20;"));
|
||||
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY);
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(queryV2, equalTo("""
|
||||
from(bucket:"origin")
|
||||
\t|> range(start:-100y, stop:100y)
|
||||
|
@ -159,11 +159,11 @@ public class InfluxFilterCriteriaQueryCreatorImplTest {
|
|||
FilterCriteria criteria = createBaseCriteria();
|
||||
criteria.setOrdering(FilterCriteria.Ordering.ASCENDING);
|
||||
|
||||
String query = instanceV1.createQuery(criteria, RETENTION_POLICY);
|
||||
String query = instanceV1.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(query,
|
||||
equalTo("SELECT \"value\"::field,\"item\"::tag FROM \"origin\".\"sampleItem\" ORDER BY time ASC;"));
|
||||
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY);
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(queryV2, equalTo("""
|
||||
from(bucket:"origin")
|
||||
\t|> range(start:-100y, stop:100y)
|
||||
|
@ -177,7 +177,7 @@ public class InfluxFilterCriteriaQueryCreatorImplTest {
|
|||
FilterCriteria criteria = createBaseCriteria();
|
||||
criteria.setOrdering(FilterCriteria.Ordering.DESCENDING);
|
||||
criteria.setPageSize(1);
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY);
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(queryV2, equalTo("""
|
||||
from(bucket:"origin")
|
||||
\t|> range(start:-100y, stop:100y)
|
||||
|
@ -200,11 +200,11 @@ public class InfluxFilterCriteriaQueryCreatorImplTest {
|
|||
when(metadataRegistry.get(metadataKey))
|
||||
.thenReturn(new Metadata(metadataKey, "measurementName", Map.of("key1", "val1", "key2", "val2")));
|
||||
|
||||
String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY);
|
||||
String queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(queryV1, equalTo(
|
||||
"SELECT \"value\"::field,\"item\"::tag FROM \"origin\".\"measurementName\" WHERE item = 'sampleItem' ORDER BY time DESC;"));
|
||||
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY);
|
||||
String queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(queryV2, equalTo("""
|
||||
from(bucket:"origin")
|
||||
\t|> range(start:-100y, stop:100y)
|
||||
|
@ -215,11 +215,11 @@ public class InfluxFilterCriteriaQueryCreatorImplTest {
|
|||
when(metadataRegistry.get(metadataKey))
|
||||
.thenReturn(new Metadata(metadataKey, "", Map.of("key1", "val1", "key2", "val2")));
|
||||
|
||||
queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY);
|
||||
queryV1 = instanceV1.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(queryV1,
|
||||
equalTo("SELECT \"value\"::field,\"item\"::tag FROM \"origin\".\"sampleItem\" ORDER BY time DESC;"));
|
||||
|
||||
queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY);
|
||||
queryV2 = instanceV2.createQuery(criteria, RETENTION_POLICY, null);
|
||||
assertThat(queryV2, equalTo("""
|
||||
from(bucket:"origin")
|
||||
\t|> range(start:-100y, stop:100y)
|
||||
|
|
|
@ -212,9 +212,10 @@ public class JdbcMapper {
|
|||
logTime("alterTableColumn", timerStart, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
protected void storeItemValue(Item item, State itemState, @Nullable ZonedDateTime date) throws JdbcException {
|
||||
protected void storeItemValue(Item item, State itemState, @Nullable ZonedDateTime date, @Nullable String alias)
|
||||
throws JdbcException {
|
||||
logger.debug("JDBC::storeItemValue: item={} state={} date={}", item, itemState, date);
|
||||
String tableName = getTable(item);
|
||||
String tableName = getTable(item, alias);
|
||||
long timerStart = System.currentTimeMillis();
|
||||
if (date == null) {
|
||||
conf.getDBDAO().doStoreItemValue(item, itemState, new ItemVO(tableName, null));
|
||||
|
@ -353,8 +354,8 @@ public class JdbcMapper {
|
|||
}
|
||||
}
|
||||
|
||||
protected String getTable(Item item) throws JdbcException {
|
||||
String itemName = item.getName();
|
||||
protected String getTable(Item item, @Nullable String alias) throws JdbcException {
|
||||
String itemName = alias != null ? alias : item.getName();
|
||||
if (!initialized) {
|
||||
throw new JdbcException("Not initialized, unable to find table for item " + itemName);
|
||||
}
|
||||
|
|
|
@ -137,27 +137,26 @@ public class JdbcPersistenceService extends JdbcMapper implements ModifiablePers
|
|||
|
||||
@Override
|
||||
public void store(Item item) {
|
||||
scheduler.execute(() -> internalStore(item, null, item.getState()));
|
||||
scheduler.execute(() -> internalStore(item, null, item.getState(), null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(Item item, @Nullable String alias) {
|
||||
// alias is not supported
|
||||
scheduler.execute(() -> internalStore(item, null, item.getState()));
|
||||
scheduler.execute(() -> internalStore(item, null, item.getState(), alias));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(Item item, ZonedDateTime date, State state) {
|
||||
scheduler.execute(() -> internalStore(item, date, state));
|
||||
scheduler.execute(() -> internalStore(item, date, state, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(Item item, ZonedDateTime date, State state, @Nullable String alias) {
|
||||
// alias is not supported
|
||||
scheduler.execute(() -> internalStore(item, date, state));
|
||||
scheduler.execute(() -> internalStore(item, date, state, alias));
|
||||
}
|
||||
|
||||
private synchronized void internalStore(Item item, @Nullable ZonedDateTime date, State state) {
|
||||
private synchronized void internalStore(Item item, @Nullable ZonedDateTime date, State state,
|
||||
@Nullable String alias) {
|
||||
// Do not store undefined/uninitialized data
|
||||
if (state instanceof UnDefType) {
|
||||
logger.debug("JDBC::store: ignore Item '{}' because it is UnDefType", item.getName());
|
||||
|
@ -171,7 +170,7 @@ public class JdbcPersistenceService extends JdbcMapper implements ModifiablePers
|
|||
}
|
||||
try {
|
||||
long timerStart = System.currentTimeMillis();
|
||||
storeItemValue(item, state, date);
|
||||
storeItemValue(item, state, date, alias);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("JDBC: Stored item '{}' as '{}' in SQL database at {} in {} ms.", item.getName(), state,
|
||||
new Date(), System.currentTimeMillis() - timerStart);
|
||||
|
@ -190,12 +189,24 @@ public class JdbcPersistenceService extends JdbcMapper implements ModifiablePers
|
|||
* Queries the {@link PersistenceService} for data with a given filter
|
||||
* criteria
|
||||
*
|
||||
* @param filter
|
||||
* the filter to apply to the query
|
||||
* @param filter the filter to apply to the query
|
||||
* @return a time series of items
|
||||
*/
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter) {
|
||||
return query(filter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the {@link PersistenceService} for data with a given filter
|
||||
* criteria
|
||||
*
|
||||
* @param filter the filter to apply to the query
|
||||
* @param alias for the item
|
||||
* @return a time series of items
|
||||
*/
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter, @Nullable String alias) {
|
||||
if (!checkDBAccessability()) {
|
||||
logger.warn("JDBC::query: database not connected, query aborted for item '{}'", filter.getItemName());
|
||||
return List.of();
|
||||
|
@ -231,9 +242,11 @@ public class JdbcPersistenceService extends JdbcMapper implements ModifiablePers
|
|||
}
|
||||
}
|
||||
|
||||
String table = itemNameToTableNameMap.get(itemName);
|
||||
String localAlias = alias != null ? alias : itemName;
|
||||
String table = itemNameToTableNameMap.get(localAlias);
|
||||
if (table == null) {
|
||||
logger.debug("JDBC::query: unable to find table for item with name: '{}', no data in database.", itemName);
|
||||
logger.debug("JDBC::query: unable to find table for item with name or alias: '{}', no data in database.",
|
||||
localAlias);
|
||||
return List.of();
|
||||
}
|
||||
|
||||
|
|
|
@ -187,6 +187,11 @@ public class JpaPersistenceService implements QueryablePersistenceService {
|
|||
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter) {
|
||||
return query(filter, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter, @Nullable String alias) {
|
||||
logger.debug("Querying for historic item: {}", filter.getItemName());
|
||||
|
||||
if (!initialized) {
|
||||
|
@ -235,7 +240,7 @@ public class JpaPersistenceService implements QueryablePersistenceService {
|
|||
|
||||
logger.debug("Creating query...");
|
||||
Query query = em.createQuery(queryString);
|
||||
query.setParameter("itemName", item.getName());
|
||||
query.setParameter("itemName", alias != null ? alias : item.getName());
|
||||
if (hasBeginDate) {
|
||||
query.setParameter("beginDate", Date.from(filter.getBeginDate().toInstant()));
|
||||
}
|
||||
|
|
|
@ -247,6 +247,15 @@ public class MongoDBPersistenceService implements ModifiablePersistenceService {
|
|||
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter) {
|
||||
return query(filter, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter, @Nullable String alias) {
|
||||
String realItemName = filter.getItemName();
|
||||
if (alias != null) {
|
||||
filter.setItemName(alias);
|
||||
}
|
||||
MongoCollection<Document> collection = prepareCollection(filter);
|
||||
// If collection creation failed, return nothing.
|
||||
if (collection == null) {
|
||||
|
@ -259,8 +268,6 @@ public class MongoDBPersistenceService implements ModifiablePersistenceService {
|
|||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String realItemName = filter.getItemName();
|
||||
if (realItemName == null) {
|
||||
logger.warn("Item name is missing in filter {}", filter);
|
||||
return Collections.emptyList();
|
||||
|
@ -354,7 +361,8 @@ public class MongoDBPersistenceService implements ModifiablePersistenceService {
|
|||
}
|
||||
|
||||
String realItemName = item.getName();
|
||||
String collectionName = collectionPerItem ? realItemName : this.collection;
|
||||
String name = (alias != null) ? alias : realItemName;
|
||||
String collectionName = collectionPerItem ? name : this.collection;
|
||||
|
||||
@Nullable
|
||||
MongoCollection<Document> collection = connectToCollection(collectionName);
|
||||
|
@ -364,7 +372,6 @@ public class MongoDBPersistenceService implements ModifiablePersistenceService {
|
|||
return;
|
||||
}
|
||||
|
||||
String name = (alias != null) ? alias : realItemName;
|
||||
Object value = MongoDBTypeConversions.convertValue(state);
|
||||
|
||||
Document obj = new Document();
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
*/
|
||||
package org.openhab.persistence.mongodb.internal;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.time.Instant;
|
||||
|
@ -30,6 +29,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import org.bson.Document;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
@ -46,6 +46,7 @@ import org.openhab.core.library.types.DecimalType;
|
|||
import org.openhab.core.library.types.HSBType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.RawType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.persistence.FilterCriteria;
|
||||
import org.openhab.core.persistence.HistoricItem;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
@ -206,7 +207,7 @@ public class MongoDBPersistenceServiceTest {
|
|||
|
||||
// Verification
|
||||
MongoCollection<Document> collection = database.getCollection("testCollection");
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
assertEquals(1, documents.size()); // Assert that there is only one document
|
||||
|
||||
|
@ -244,7 +245,7 @@ public class MongoDBPersistenceServiceTest {
|
|||
|
||||
// Verification
|
||||
MongoCollection<Document> collection = database.getCollection("testCollection");
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
assertEquals(1, documents.size()); // Assert that there is only one document
|
||||
|
||||
|
@ -284,7 +285,7 @@ public class MongoDBPersistenceServiceTest {
|
|||
|
||||
// Verification
|
||||
MongoCollection<Document> collection = database.getCollection("testCollection");
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
assertEquals(2, documents.size()); // Assert that there are two documents
|
||||
|
||||
|
@ -326,7 +327,7 @@ public class MongoDBPersistenceServiceTest {
|
|||
|
||||
// Verification
|
||||
MongoCollection<Document> collection = database.getCollection("testCollection");
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
assertEquals(2, documents.size()); // Assert that there are two documents
|
||||
|
||||
|
@ -366,7 +367,7 @@ public class MongoDBPersistenceServiceTest {
|
|||
|
||||
// Verification
|
||||
MongoCollection<Document> collection = database.getCollection("testCollection");
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
assertEquals(1, documents.size()); // Assert that there is only one document
|
||||
|
||||
|
@ -378,6 +379,48 @@ public class MongoDBPersistenceServiceTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the reading of String Items stored with an alias
|
||||
*
|
||||
* @param dbContainer The container running the MongoDB instance.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("org.openhab.persistence.mongodb.internal.DataCreationHelper#provideDatabaseBackends")
|
||||
public void testQueryStringWithAlias(DatabaseTestContainer dbContainer) {
|
||||
try {
|
||||
SetupResult setupResult = DataCreationHelper.setupMongoDB("testCollection", dbContainer);
|
||||
MongoDBPersistenceService service = setupResult.service;
|
||||
MongoDatabase database = setupResult.database;
|
||||
|
||||
service.activate(setupResult.bundleContext, setupResult.config);
|
||||
MongoCollection<Document> collection = database.getCollection("testCollection");
|
||||
|
||||
StringItem item = DataCreationHelper.createStringItem("TestItem", "TestValue");
|
||||
try {
|
||||
Mockito.when(setupResult.itemRegistry.getItem("TestItem")).thenReturn(item);
|
||||
} catch (ItemNotFoundException e) {
|
||||
}
|
||||
|
||||
String alias = "AliasName";
|
||||
|
||||
Document obj = new Document();
|
||||
obj.put(MongoDBFields.FIELD_ID, new ObjectId());
|
||||
obj.put(MongoDBFields.FIELD_ITEM, alias);
|
||||
obj.put(MongoDBFields.FIELD_REALNAME, "TestItem");
|
||||
obj.put(MongoDBFields.FIELD_TIMESTAMP, new Date());
|
||||
obj.put(MongoDBFields.FIELD_VALUE, "TestValue");
|
||||
collection.insertOne(obj);
|
||||
|
||||
// Execution
|
||||
FilterCriteria filter = DataCreationHelper.createFilterCriteria("TestItem");
|
||||
@NonNull
|
||||
Iterable<@NonNull HistoricItem> result = service.query(filter, alias);
|
||||
VerificationHelper.verifyQueryResult(result, new StringType("TestValue"));
|
||||
} finally {
|
||||
dbContainer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the query method of MongoDBPersistenceService with NumberItems in a single collection.
|
||||
*
|
||||
|
@ -607,7 +650,7 @@ public class MongoDBPersistenceServiceTest {
|
|||
|
||||
// Verification
|
||||
MongoCollection<Document> collection = database.getCollection("testCollection");
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
assertEquals(1, documents.size()); // Assert that there is only one document
|
||||
|
||||
|
@ -735,7 +778,7 @@ public class MongoDBPersistenceServiceTest {
|
|||
service.store(item, null);
|
||||
|
||||
// Verification
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
assertEquals(1, documents.size()); // Assert that there is only one document
|
||||
|
||||
|
@ -793,7 +836,6 @@ public class MongoDBPersistenceServiceTest {
|
|||
|
||||
/**
|
||||
* Tests the toString of a MongoDBItem
|
||||
*
|
||||
*
|
||||
* @param item The item to store in the database.
|
||||
*/
|
||||
|
@ -840,7 +882,7 @@ public class MongoDBPersistenceServiceTest {
|
|||
|
||||
// Verification
|
||||
MongoCollection<Document> collection = database.getCollection("TestItem");
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
assertEquals(1, documents.size()); // Assert that there is only one document
|
||||
|
||||
|
@ -880,8 +922,8 @@ public class MongoDBPersistenceServiceTest {
|
|||
service.store(item, now, historicState, "AliasName");
|
||||
|
||||
// Verification
|
||||
MongoCollection<Document> collection = database.getCollection("TestItem");
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
MongoCollection<Document> collection = database.getCollection("AliasName");
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
assertEquals(1, documents.size()); // Assert that there is only one document
|
||||
|
||||
|
@ -919,7 +961,7 @@ public class MongoDBPersistenceServiceTest {
|
|||
// Verification
|
||||
MongoCollection<Document> collection = database.getCollection("testcollection");
|
||||
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
assertEquals(1, documents.size()); // Assert that there is the other document
|
||||
|
||||
|
@ -959,7 +1001,7 @@ public class MongoDBPersistenceServiceTest {
|
|||
MongoCollection<Document> collection = database.getCollection("testcollection");
|
||||
|
||||
// Query the database for all data points
|
||||
List<Document> documents = (ArrayList<Document>) collection.find().into(new ArrayList<>());
|
||||
List<Document> documents = collection.find().into(new ArrayList<>());
|
||||
|
||||
// Create a set of the returned data points
|
||||
Set<PersistenceTestItem> returnedData = documents.stream()
|
||||
|
|
|
@ -333,7 +333,7 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
if (oldValue != null && !oldValue.equals(value)) {
|
||||
logger.debug(
|
||||
"Discarding value {} for item {} with timestamp {} because a new value ({}) arrived with the same timestamp.",
|
||||
oldValue, name, now, value);
|
||||
oldValue, item.getName(), now, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,6 +411,11 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter) {
|
||||
return query(filter, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter, @Nullable String alias) {
|
||||
ZonedDateTime filterBeginDate = filter.getBeginDate();
|
||||
ZonedDateTime filterEndDate = filter.getEndDate();
|
||||
if (filterBeginDate != null && filterEndDate != null && filterBeginDate.isAfter(filterEndDate)) {
|
||||
|
@ -424,9 +429,10 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
}
|
||||
logger.trace("Querying rrd4j database for item '{}'", itemName);
|
||||
|
||||
String localAlias = alias != null ? alias : itemName;
|
||||
RrdDb db = null;
|
||||
try {
|
||||
db = getDB(itemName, false);
|
||||
db = getDB(localAlias, false);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to open rrd4j database '{}' for querying ({})", itemName, e.toString());
|
||||
return List.of();
|
||||
|
|
|
@ -38,6 +38,8 @@ import org.openhab.core.items.GroupItem;
|
|||
import org.openhab.core.items.Item;
|
||||
import org.openhab.core.items.ItemNotFoundException;
|
||||
import org.openhab.core.library.items.NumberItem;
|
||||
import org.openhab.core.persistence.registry.PersistenceServiceConfiguration;
|
||||
import org.openhab.core.persistence.registry.PersistenceServiceConfigurationRegistry;
|
||||
import org.openhab.core.ui.chart.ChartProvider;
|
||||
import org.openhab.core.ui.items.ItemUIRegistry;
|
||||
import org.openhab.persistence.rrd4j.internal.RRD4jPersistenceService;
|
||||
|
@ -106,13 +108,16 @@ public class RRD4jChartServlet implements Servlet, ChartProvider {
|
|||
private final HttpService httpService;
|
||||
private final ItemUIRegistry itemUIRegistry;
|
||||
private final TimeZoneProvider timeZoneProvider;
|
||||
private final PersistenceServiceConfigurationRegistry persistenceServiceConfigurationRegistry;
|
||||
|
||||
@Activate
|
||||
public RRD4jChartServlet(final @Reference HttpService httpService, final @Reference ItemUIRegistry itemUIRegistry,
|
||||
final @Reference TimeZoneProvider timeZoneProvider) {
|
||||
final @Reference TimeZoneProvider timeZoneProvider,
|
||||
final @Reference PersistenceServiceConfigurationRegistry persistenceServiceConfigurationRegistry) {
|
||||
this.httpService = httpService;
|
||||
this.itemUIRegistry = itemUIRegistry;
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
this.persistenceServiceConfigurationRegistry = persistenceServiceConfigurationRegistry;
|
||||
}
|
||||
|
||||
@Activate
|
||||
|
@ -179,10 +184,10 @@ public class RRD4jChartServlet implements Servlet, ChartProvider {
|
|||
* @param item the item to add a line for
|
||||
* @param counter defines the number of the datasource and is used to determine the line color
|
||||
*/
|
||||
protected void addLine(RrdGraphDef graphDef, Item item, int counter) {
|
||||
protected void addLine(RrdGraphDef graphDef, Item item, @Nullable String alias, int counter) {
|
||||
Color color = LINECOLORS[counter % LINECOLORS.length];
|
||||
String label = itemUIRegistry.getLabel(item.getName());
|
||||
String rrdName = RRD4jPersistenceService.getDatabasePath(item.getName()).toString();
|
||||
String rrdName = RRD4jPersistenceService.getDatabasePath(alias != null ? alias : item.getName()).toString();
|
||||
ConsolFun consolFun;
|
||||
if (label != null && label.contains("[") && label.contains("]")) {
|
||||
label = label.substring(0, label.indexOf('['));
|
||||
|
@ -251,14 +256,18 @@ public class RRD4jChartServlet implements Servlet, ChartProvider {
|
|||
graphDef.setFont(FontTag.TITLE, new Font("SansSerif", Font.PLAIN, 15));
|
||||
graphDef.setFont(FontTag.DEFAULT, new Font("SansSerif", Font.PLAIN, 11));
|
||||
|
||||
PersistenceServiceConfiguration config = persistenceServiceConfigurationRegistry
|
||||
.get(RRD4jPersistenceService.SERVICE_ID);
|
||||
|
||||
int seriesCounter = 0;
|
||||
|
||||
// Loop through all the items
|
||||
if (items != null) {
|
||||
String[] itemNames = items.split(",");
|
||||
for (String itemName : itemNames) {
|
||||
String alias = config != null ? config.getAliases().get(itemName) : null;
|
||||
Item item = itemUIRegistry.getItem(itemName);
|
||||
addLine(graphDef, item, seriesCounter++);
|
||||
addLine(graphDef, item, alias, seriesCounter++);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,7 +278,8 @@ public class RRD4jChartServlet implements Servlet, ChartProvider {
|
|||
Item item = itemUIRegistry.getItem(groupName);
|
||||
if (item instanceof GroupItem groupItem) {
|
||||
for (Item member : groupItem.getMembers()) {
|
||||
addLine(graphDef, member, seriesCounter++);
|
||||
String alias = config != null ? config.getAliases().get(member.getName()) : null;
|
||||
addLine(graphDef, member, alias, seriesCounter++);
|
||||
}
|
||||
} else {
|
||||
throw new ItemNotFoundException("Item '" + item.getName() + "' defined in groups is not a group.");
|
||||
|
|
|
@ -17,7 +17,10 @@ import java.nio.file.Path;
|
|||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
@ -30,6 +33,8 @@ import org.openhab.core.items.ItemNotFoundException;
|
|||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.core.persistence.PersistenceService;
|
||||
import org.openhab.core.persistence.PersistenceServiceRegistry;
|
||||
import org.openhab.core.persistence.registry.PersistenceServiceConfiguration;
|
||||
import org.openhab.core.persistence.registry.PersistenceServiceConfigurationRegistry;
|
||||
import org.openhab.persistence.rrd4j.internal.RRD4jPersistenceService;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
@ -51,13 +56,16 @@ public class RRD4jCommandExtension extends AbstractConsoleCommandExtension imple
|
|||
false);
|
||||
|
||||
private final PersistenceServiceRegistry persistenceServiceRegistry;
|
||||
private final PersistenceServiceConfigurationRegistry persistenceServiceConfigurationRegistry;
|
||||
private final ItemRegistry itemRegistry;
|
||||
|
||||
@Activate
|
||||
public RRD4jCommandExtension(final @Reference PersistenceServiceRegistry persistenceServiceRegistry,
|
||||
final @Reference ItemRegistry itemRegistry) {
|
||||
final @Reference ItemRegistry itemRegistry,
|
||||
final @Reference PersistenceServiceConfigurationRegistry persistenceServiceConfigurationRegistry) {
|
||||
super(RRD4jPersistenceService.SERVICE_ID, "Interact with the RRD4j persistence service.");
|
||||
this.persistenceServiceRegistry = persistenceServiceRegistry;
|
||||
this.persistenceServiceConfigurationRegistry = persistenceServiceConfigurationRegistry;
|
||||
this.itemRegistry = itemRegistry;
|
||||
}
|
||||
|
||||
|
@ -104,6 +112,11 @@ public class RRD4jCommandExtension extends AbstractConsoleCommandExtension imple
|
|||
Collections.sort(filenames, Comparator.naturalOrder());
|
||||
}
|
||||
|
||||
PersistenceServiceConfiguration config = persistenceServiceConfigurationRegistry
|
||||
.get(RRD4jPersistenceService.SERVICE_ID);
|
||||
Stream<Entry<String, String>> aliases = config != null ? config.getAliases().entrySet().stream()
|
||||
: Stream.empty();
|
||||
|
||||
console.println((checkOnly ? "Checking" : "Cleaning") + " RRD files...");
|
||||
int nb = 0;
|
||||
for (String filename : filenames) {
|
||||
|
@ -114,7 +127,10 @@ public class RRD4jCommandExtension extends AbstractConsoleCommandExtension imple
|
|||
} else {
|
||||
boolean itemFound;
|
||||
try {
|
||||
itemRegistry.getItem(name);
|
||||
// Map alias back to item
|
||||
String item = Objects.requireNonNull(
|
||||
aliases.filter(e -> name.equals(e.getValue())).findAny().map(e -> e.getKey()).orElse(name));
|
||||
itemRegistry.getItem(item);
|
||||
itemFound = true;
|
||||
} catch (ItemNotFoundException e) {
|
||||
itemFound = false;
|
||||
|
|
Loading…
Reference in New Issue